【问题标题】:How to mock other class functions in testing controller in Laravel如何在 Laravel 中的测试控制器中模拟其他类函数
【发布时间】:2019-11-27 13:30:23
【问题描述】:

我正在尝试在 Laravel 中测试一个控制器,它使用另一个类作为助手,它调用 API 并返回结果。

为了避免外部 API 调用,我需要模拟这个助手。

我尝试在控制器中模拟类并运行测试,但没有得到我在模拟类中的预期。

这是我的控制器方法:

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

}

我的辅助方法只是调用一个 API 并返回结果。

class TheHelper
{
    public function getResult($email){
      // some api calls
      return $result;
    }
}

这是我的测试:

public function testExample()
    {

        $helperMock = Mockery::mock(TheHelper::class);

        // Set expectations
        $helperMock ->shouldReceive('getResult')
            ->once()
            ->with('testemail@test.com')
            ->andReturn([
                'id' => '100'
            ]);

        $this->app->instance(TheHelper::class, $helperMock);

        $this->json(
            'POST',
            '/api/test_method',
            ['email' => 'testemail@test.com'])
            ->assertStatus(200);
}

我的模拟函数从未调用过。它只检查 TheHelper 方法中的真实 API

【问题讨论】:

    标签: laravel mocking integration-testing


    【解决方案1】:

    您的测试是创建一个模拟对象并将该模拟对象绑定到 Laravel 服务容器中。但是,您的控制器并没有从 Laravel 服务容器中提取 TheHelper 实例;它使用new 关键字手动实例化它。使用new关键字是PHP的核心,完全不涉及Laravel。

    您的测试显示代码中存在问题。 TheHelper 是您的方法的依赖项,因此应该传递到方法中,而不是在方法内部创建。

    你要么需要更新你的控制器方法以使用依赖注入,以便 Laravel 可以自动从其容器中解析 TheHelper 依赖,要么你需要将 new 关键字替换为对 Laravel 容器的调用。

    使用依赖注入:

    public function A(Request $request, TheHelper $helper)
    {
        $result = $helper->getResult($request->email);
        // rest of function...
    }
    

    从容器中手动拉取:

    public function A(Request $request)
    {
        $helper = app(TheHelper::class);
        $result = $helper->getResult($request->email);
        // rest of function...
    }
    

    【讨论】:

    • 谢谢,我使用了依赖注入的方式,它奏效了。我确信第二种方法也有效
    • 感谢您的清晰解释!这非常有效!
    猜你喜欢
    • 2014-06-29
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 2019-10-20
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多