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
JavaScript
x
Route::get('/api/{project}', [ProjectController::class, 'show']);
ProjectController.php
JavaScript
class ProjectController extends Controller
{
public function show(Project $project)
{
$state = $project->getState();
return response()->json($state);
}
}
ProjectControllerTest.php
JavaScript
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
JavaScript
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
JavaScript
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
JavaScript
Route::get('/projects/{project}', [ProjectController::class, 'show']);
ProjectController
JavaScript
<?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
JavaScript
<?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'
]);
}
}