【问题标题】:How to Mock the Request Class in Laravel?如何在 Laravel 中模拟请求类?
【发布时间】:2018-10-26 18:18:27
【问题描述】:

我正在尝试测试一个依赖于

的函数
$request->all();

在一个方法中。如何模拟 Request 类以便 $request->all(); 返回

['includes' => ['some_val','another_val'] 

在测试中?

【问题讨论】:

  • Don't(见底部的消息)。
  • 这应该是公认的答案。

标签: laravel mocking phpunit


【解决方案1】:

我建议你使用mockery/mockery

我现在不记得 Laravel 是否附带它(我想是的)。

无论哪种方式,您都必须这样做:

在你的方法测试中做:

app()->bind(\Illuminate\Http\Request::class, function () {
    $mock = \Mockery::mock(\Illuminate\Http\Request::class)->makePartial();
    $mock->shouldReceive('all')->andReturn(['includes' => ['some_val','another_val']]);

    return $mock;
});

你正在做的是:

  • 将 mock 绑定到 Request,所以当您执行 yourMethod(Request $request) 时,它将实例化您的 mock 而不是真正的类。
  • \Mockery::mock(CLASS)->makePartial(); 将首先创建该类的模拟,然后 (makePartial()) 将允许您使用其他非模拟方法可用(使用真实方法),因此您未模拟的任何方法都会运行真实代码。
  • shouldReceive 将允许被模拟的类使用模拟方法(shouldReceive 的参数),因此我们正在模拟 all 方法并返回您想要的值,在本例中为您发布的数组。
  • 最后,我们必须将模拟作为实例返回。

正如@devk 所说,Laravel 不建议模拟 Request 类,所以不要这样做,但如果你需要模拟任何其他对象,你可以使用上面的代码,它会完美地工作。

【讨论】:

    【解决方案2】:

    根据https://stackoverflow.com/a/61903688/135114, 如果

    1. 您的被测函数采用$request 参数,
    2. 您不需要对请求做一些时髦的事情 - 真正的路径对您来说已经足够好了

    ...那么您不需要“模拟”请求(例如,嘲弄),
    你可以创建一个Request并传递它,例如

    public function test_myFunc_condition_expectedResult() {
        ...
        $mockRequest = Request::create('/path/that/I_want', 'GET'); 
        $this->assertTrue($myClass->myFuncThat($mockRequest));
    }
    

    【讨论】:

      【解决方案3】:

      正如 devk 所说,不要模拟请求。但是 Laravel 允许你构建一个实际的请求,然后在你的测试中调用你的控制器,如下所示:

      public function testPostRequest() {
          $response = $this->post(
              '/my-custom-route',
              ['includes' => ['some_val','another_val'] 
          );
      }
      

      【讨论】:

      • 这是一个可行的解决方案,因为他可能只想进行单元测试,而您正在做功能测试。
      猜你喜欢
      • 2018-03-03
      • 2021-04-30
      • 2019-08-07
      • 2021-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-16
      • 1970-01-01
      相关资源
      最近更新 更多