【发布时间】:2022-01-09 00:01:18
【问题描述】:
我有一个依赖于 BillingService 的 Controller,而 BillingService 又依赖于 UserService。
我需要调用 Controller 方法 getPlans,在这个调用中我需要模拟两个函数:
- BillingService 中的 loadPlans
- UserService 中的 getUsage
这是完整的例子:
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 ?
}
}
最后,在我的测试中,我只是调用:
getJson(action([BillingPlanController::class, "getPlans"]));
在其他测试中,我能够模拟单个服务,但在这种情况下,我不知道如何编写模拟。
对不起,如果我没有提供任何“尝试”,但我真的不知道我该怎么做。
更新
我尝试使用 partialMock 和 mock,但出现此错误(调用 getUsage 时) - 使用了 partialMock,因为我只是需要模拟一个函数:
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"]));
【问题讨论】:
-
如果你完全模拟而不是部分模拟服务会发生什么?
-
我在第一个服务上使用了 partialMock,因为 getPlans 是我需要测试的真正功能 - 如果我完全模拟他,功能未定义并且我得到:收到 Mockery_3_App_Modules_Billing_Services_BillingPlanService::getPlans(),但是没有指定期望我正在调用控制器,因为在此调用之后,我也需要测试响应。它是一个集成测试
标签: laravel mocking phpunit php-pest