In my Laravel app I have a controller with a method to show a particular resource. E.g. say the url is /widgets/26
My controller method might work like so:
Class WidgetsController {
protected $widgets;
public function __construct(WidgetsRepository $widgets)
{
$this->widgets = $widgets;
}
public function show($id)
{
$widget = $this->widgets->find($id);
return view('widgets.show')->with(compact('widget'));
}
}
As we can see my WidgetsController
has a WidgetsRepository
dependency. In a unit test for the show
method, how can I mock this dependency so that I don't actually have to call the repository and instead just return a hard-coded widget
?
Unit test start:
function test_it_shows_a_single_widget()
{
// how can I tell the WidgetsController to be instaniated with a mocked WidgetRepository?
$response = $this->action('GET', 'WidgetsController@show', ['id' => 1]);
// somehow mock the call to the repository's `find()` method and give a hard-coded return value
// continue with assertions
}
You can mock the repository class and load it into the IoC container.
So when Laravel gets to your controller, it will find it already in there and will resolve your mock instead of instantiating a new one.
function test_it_shows_a_single_widget()
{
// mock the repository
$repository = Mockery::mock(WidgetRepository::class);
$repository->shouldReceive('find')
->with(1)
->once()
->andReturn(new Widget([]));
// load the mock into the IoC container
$this->app->instance(WidgetRepository::class, $repository);
// when making your call, your controller will use your mock
$response = $this->action('GET', 'WidgetsController@show', ['id' => 1]);
// continue with assertions
// ...
}
A similar setup has been tested and working fine in Laravel 5.3.21.
There was a similar question on Laracasts. The person had something like this ( https://laracasts.com/discuss/channels/general-discussion/mockery-error?page=1 ) :
public function testMe()
{
// Arrange
$classContext = Mockery::mock('\FullNamespace\To\Class');
$classContext->shouldReceive('id')->andReturn(99);
$resources = new ResourcesRepo($classContext);
// Act
// Assert
}
You could however put this as well on the setUp method if using PHPUnit method ( http://docs.mockery.io/en/latest/reference/phpunit_integration.html ).
Hope this is helpful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With