Reputation: 55
I am trying to test a controller in Laravel that uses another class as a helper which calls an API and returns the result.
To avoid external API calls, I need to mock this helper.
I tried to mock the class inside the controller and run the test but I didn't get what I expected in mock class.
this is my controller method:
public function A(Request $request){
$helper = new TheHelper();
$result = $helper->getResult($request->email);
if($result){
return response()->json([
'success' => true,
'message' => "result found",
], 200);
}else{
return response()->json([
'success' => false,
'message' => "no result",
], 500);
}
}
My helper method simply calls an API and returns the result.
class TheHelper
{
public function getResult($email){
// some api calls
return $result;
}
}
Here is my test:
public function testExample()
{
$helperMock = Mockery::mock(TheHelper::class);
// Set expectations
$helperMock ->shouldReceive('getResult')
->once()
->with('[email protected]')
->andReturn([
'id' => '100'
]);
$this->app->instance(TheHelper::class, $helperMock);
$this->json(
'POST',
'/api/test_method',
['email' => '[email protected]'])
->assertStatus(200);
}
My mock function never called. it only checks with the real API inside TheHelper method
Upvotes: 0
Views: 2446
Reputation: 62228
Your test is creating a mock object and binding that mock object into the Laravel service container. However, your controller is not pulling a TheHelper
instance from the Laravel service container; it is manually instantiating it with the new
keyword. Using the new
keyword is core PHP, and does not involve Laravel at all.
Your test is showing you an issue in your code. TheHelper
is a dependency of your method, and should therefore be passed into the method instead of being created inside the method.
You either need to update your controller method to use dependency injection, so that Laravel can automatically resolve the TheHelper
dependency from its container, or you need to replace your new
keyword with a call into the Laravel container.
Using dependency injection:
public function A(Request $request, TheHelper $helper)
{
$result = $helper->getResult($request->email);
// rest of function...
}
Manually pull from the container:
public function A(Request $request)
{
$helper = app(TheHelper::class);
$result = $helper->getResult($request->email);
// rest of function...
}
Upvotes: 5