【问题标题】:How can I mock a service class inside a Laravel Job?如何在 Laravel 作业中模拟服务类?
【发布时间】:2023-01-13 04:36:47
【问题描述】:

我想模拟调用第三方的服务,但我无法弄清楚。

我有一个控制器方法,该方法在其上注入了服务并执行以下操作:

public function store(Request $request, MyService $myService)
{
    $data = $request->validated();

    $myService->create($data, $request->user());

    return response()->json();
}

在这项服务中,我调用了一个工作来做其他事情:

MyJob::dispatch($manager);

我的工作是这样构建的:

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();
}

在 ManagementService 中,我想模拟函数 callApi:

public function startManagement()
{
    $data = $this->callApi('/thirdparty/call');

    return $data;
}

所以,在我的测试中,我尝试模拟 ManagementService 并调用我的路线谁做所有这些事情

$this->mock(ManagementService::class, function ($mock) {
    $mock->shouldReceive('callApi')->andReturn('none');
});

$response = $this->actingAs(User::factory()->create())->post('/myroute', [
    'manager_id' => 4,
]);

但似乎这个模拟从未使用过,它仍然进入“正常”管理服务,因为当我在启动测试时在 startManagement 方法中转储 $data 时,它没有返回“无”。

我究竟做错了什么?

谢谢

【问题讨论】:

  • 我会做的只是嘲笑这份工作。您可以模拟对它的调用,然后断言是否使用所需/预期的输入调用/触发了该作业。然后在单元测试中,你专门测试工作。阅读this part
  • 如果我对工作进行单元测试,我的工作仍然有服务。问题是一样的,我没有嘲笑我的服务

标签: laravel testing service mocking laravel-service-container


【解决方案1】:

您发布的代码不是很清楚,但如果我理解正确的话,您喜欢模拟 hard dependency 这就是为什么您的模拟从未调用过的原因,因为您从未注册过它。

只需在 mock 方法中的类名前添加字符串 overload 即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 2021-10-12
    • 2011-04-01
    • 2020-03-04
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多