Installation:
composer require eloquent/phony-phpunit # For PHPUnit
# or
composer require eloquent/phony-kahlan # For Kahlan
Basic Mock Creation:
use Eloquent\Phony\Phpunit\Phony; // For PHPUnit
$handle = Phony::mock('App\Services\UserService');
$mock = $handle->get();
Stubbing a Method:
$handle->findUser->with(1)->returns(['id' => 1, 'name' => 'John']);
$user = $mock->findUser(1); // Returns ['id' => 1, 'name' => 'John']
Verification:
$handle->findUser->calledWith(1); // Asserts method was called with arg 1
Testing a Laravel Controller:
public function testUserProfile()
{
$handle = Phony::mock('App\Http\Controllers\UserController');
$controller = $handle->get();
$handle->getUser->with(1)->returns(['name' => 'John']);
$response = $controller->profile(1);
$this->assertEquals('John', $response['name']);
$handle->getUser->calledWith(1);
}
Dependency Injection Mocking:
// In a Laravel service provider
$this->app->bind('App\Services\PaymentGateway', function () {
$handle = Phony::mock('App\Services\PaymentGateway');
$handle->charge->with(100)->returns(true);
return $handle->get();
});
Stubbing Database Interactions:
$handle = Phony::mock('App\Models\User');
$handle->find->with(1)->returns(new User(['name' => 'John']));
$user = User::find(1); // Returns mocked user
Spying on External API Calls:
$handle = Phony::mock('GuzzleHttp\Client');
$handle->get->with('https://api.example.com/data')->returns(['data' => 'test']);
$client = $handle->get();
$response = $client->get('https://api.example.com/data');
$handle->get->calledWith('https://api.example.com/data');
Testing Middleware:
$handle = Phony::mock('App\Http\Middleware\Authenticate');
$middleware = $handle->get();
$handle->handle->with($request, $next)->returns($response);
Laravel Service Container:
Use Phony::mock() in setUp() to mock dependencies before each test.
public function setUp(): void
{
parent::setUp();
$this->mock = Phony::mock('App\Services\SomeService');
$this->app->instance('App\Services\SomeService', $this->mock->get());
}
Trait Mocking:
$handle = Phony::mock('App\Traits\Loggable');
$trait = $handle->get();
$handle->log->with('message')->returns(true);
Static Method Stubbing:
$handle = Phony::mock('App\Helpers\StringHelper');
$handle->staticMethod->returns('static result');
Exception Stubbing:
$handle->method->throws(new \RuntimeException('Error'));
Generator Stubbing:
$handle->getItems->returns(function () {
yield 'item1';
yield 'item2';
});
Archived Package:
mockery/mockery or phpunit/phpunit for new projects.Reference Arguments:
$handle->method->withArgs([&$arg])->returns(true);
Final Classes:
final classes:
$handle = Phony::mock('App\Services\FinalService', true); // Enable proxy
Order Verification:
$handle->method1->called();
$handle->method2->called();
$handle->verifyOrder();
Hamcrest Matchers:
Detailed Verification Output: Phony provides verbose output for failed assertions. Use this to pinpoint issues:
$handle->method->calledWith('expected'); // Fails with detailed diff
Stubbing vs. Spying:
Partial Mocks:
Phony::partialMock() to mock only specific methods of a class:
$handle = Phony::partialMock('App\Models\User', ['find']);
Custom Class Names:
$handle = Phony::mock('App\Models\User', 'MockedUser');
Custom Matchers:
$handle->method->calledWith($this->customMatcher());
Mock Builders:
$builder = Phony::mockBuilder('App\Services\PaymentGateway')
->method('charge')->returns(true);
$handle = $builder->mock();
Integration with Laravel:
createApplication() to inject mocks:
protected function createApplication()
{
$app = require __DIR__.'/../../bootstrap/app.php';
$app->bind('App\Services\SomeService', function () {
return Phony::mock('App\Services\SomeService')->get();
});
return $app;
}
Generator Verification:
$handle->getItems->returns(function () {
yield 'item1';
yield 'item2';
});
$items = iterator_to_array($handle->getItems());
$this->assertEquals(['item1', 'item2'], $items);
How can I help you explore Laravel packages today?