I have a Controller that has a dependency with BillingService, and BillingService has another dependency on UserService.
I need to call the Controller method getPlans and in this call I need to mock two functions:
- loadPlans that is inside BillingService
- getUsage that is in UserService
This is the full example:
class BillingPlanController
{
public function __construct(private BillingPlanService $billingPlanService)
{
}
public function getPlans()
{
$plans = $this->billingPlanService->getPlans();
//
}
}
class BillingPlanService
{
public function __construct(private UserService $userService)
{
}
public function getPlans()
{
$plans = $this->loadPlans();
$user = auth()->user();
$usage = $this->userService->getUsage(user); // DO SOMETHING, NEED TO MOCK .. HOW ?
}
public function loadPlans()
{
// DO SOMETHING, NEED TO MOCK .. HOW ?
}
}
At the end, in my test i simply call:
getJson(action([BillingPlanController::class, "getPlans"]));
In other tests, I'm able to mock a single Service, but in this scenario, I don't know how to write the mocks.
Sorry if I don't provide any "tries", but I really don't know how I can do that.
UPDATE
I tried to use partialMock and mock, but I get this error (when getUsage is called) - partialMock is used because i just need to mock a single function:
Typed property App\Modules\Billing\Services\BillingPlanService::$userService must not be accessed before initialization
$this->mock(UserService::class, function ($mock) {
$mock->shouldReceive("getUsage")->andReturn([]);
});
$this->partialMock(BillingPlanService::class, function ($mock) {
$mock->shouldReceive("loadPlans")->andReturn([]);
});
getJson(action([BillingPlanController::class, "getPlans"]));
Your exception in your partial mock, is because when you mock the
BillingPlanService
you do not intilize theuserService
due to it being a mock. You can simply set it on the mock and i think it should work in your context.