I want to mock a service who call a third party, but I can’t figure it out.
I have a controller method who has a service injected on it and do stuff:
public function store(Request $request, MyService $myService)
{
$data = $request->validated();
$myService->create($data, $request->user());
return response()->json();
}
In this service, I call a job to do other stuffs:
MyJob::dispatch($manager);
My job is built like this:
public function __construct(private Manager $manager)
{
}
public function handle()
{
// THE SERVICE I WANT TO MOCK
$this->managementService = resolve(ManagementService::class, ['manager_id' => $this->manager->id]);
$this->doStuff();
}
private function doStuff() {
$this->managementService->startManagement();
}
In ManagementService I want to mock the function callApi:
public function startManagement()
{
$data = $this->callApi('/thirdparty/call');
return $data;
}
SO, in my test I try to mock the ManagementService and call my route who do all these things
$this->mock(ManagementService::class, function ($mock) {
$mock->shouldReceive('callApi')->andReturn('none');
});
$response = $this->actingAs(User::factory()->create())->post('/myroute', [
'manager_id' => 4,
]);
But it seems this mock is never used, it’s still going into the "normal" Management Service, because when I dump $data in the startManagement method when I launch tests, it’s not returning ‘none’.
What am I doing wrong?
Thanks
2
Answers
Figured it out by injecting my service directly in the job
And inside the service instance it via constructor instead of in the handle
Then in my test, my mock is instancied like this:
Thanks to all
The code that you post is not very clear but if i understand correctly you like to mock a hard dependency thats why your mock never called because you never register it.
Just add the string
overload
before the class name in the mock method.