I’m trying to mock a method in the Model so that I am able to test the controller api endpoint with different scenarios.
I am currently using Laravel 8 with PhpUnit and Mockery package. In the route I am using Route model binding.
api.php
Route::get('/api/{project}', [ProjectController::class, 'show']);
ProjectController.php
class ProjectController extends Controller { public function show(Project $project) { $state = $project->getState(); return response()->json($state); } }
ProjectControllerTest.php
class ProjectControllerTest extends TestCase { /** * @test * @group ProjectController */ public function shouldReturn200ForValidProjectGuid() { $project = Project::factory()->create(); $mock = Mockery::mock(Project::class); // I have also tried this, see error below // $mock = Mockery::mock(Project::class)->makePartial(); $this->app->instance(Project::class, $mock); $mock->shouldReceive('getState')->andReturn('New South Wales'); $response = $this->getJson("/api/{$project->guid}"); $response->assertStatus(200) ->assertJson([ 'data' => 'New South Wales' ]); } }
I am currently getting this error
Received Mockery_0_App_Models_Project::resolveRouteBinding(), but no expectations were specified Exception caught at [/usr/src/app/vendor/mockery/mockery/library/Mockery/Loader/EvalLoader.php(34) : eval()'d code@924
I have tried other options like makePartial() instead, however it results in the following error as well
Received Mockery_0_App_Models_Project::__construct(), but no expectations were specified Exception caught at [/usr/src/app/vendor/mockery/mockery/library/Mockery/Loader/EvalLoader.php(34) : eval()'d code@924
Any help would be much appreciated, thank you
Advertisement
Answer
You can try the following. I have changed the controller response slightly to make it work with assertJson()
.
web.php
Route::get('/projects/{project}', [ProjectController::class, 'show']);
ProjectController
<?php namespace AppHttpControllers; use AppModelsProject; class ProjectController extends Controller { /** * Display the specified resource. * * @param int $id * @return IlluminateHttpResponse */ public function show(Project $project) { return response()->json([ 'state' => $project->getState() ]); } }
ProjectControllerTest
<?php namespace TestsFeature; use AppModelsProject; use Mockery; use TestsTestCase; class ProjectControllerTest extends TestCase { /** * A basic test example. * * @return void */ public function test_example() { $mock = Mockery::mock(Project::class)->makePartial(); $mock->shouldReceive('resolveRouteBinding')->andReturnSelf(); $mock->shouldReceive('getState')->andReturn('NSW'); $this->app->instance(Project::class, $mock); $response = $this->get('/projects/1'); $response->assertStatus(200) ->assertJson([ 'state' => 'NSW' ]); } }