我应该在单元测试中模拟 $this->doSomething() 调用吗?

Should I mock a $this->doSomething() call in unit testing?

我对测试世界还很陌生,我正在努力解决嘲笑和嘲笑问题。我知道如何模拟某些被调用的 classes。幸运的是 Laravel 让这变得非常简单。

随着时间的推移,我了解到您将方法划分为例如控制器 classes 分成更小的块。因此,这些较小的方法中的每一个或多或少只做一件事,正如我听说的那样,这对测试来说更好。

让我们假设我的控制器 class 看起来像这样:

class MyController extends Controller
{
  public function myMethod($request)
  {
    $this->validateRequest($request);
    $response = App\ModelClass::doSomething();
    return response()->json($response)
  }

  protected function validateRequest($request)
  {
    // do some validation here
  }
}

据我所知,单元测试用于单独检查方法,我应该将代码分成尽可能小的块,以便更容易测试它们(因此一种方法只做一件事等)

在此示例中,单独测试 myMethod 并检查它是否调用其他方法是否是一个好习惯?我知道这行不通,但我可以像这样模拟它吗?我应该这样做吗?

\Mockery::mock('App\Http\Controllers\MyController')
  ->shouldReceive('validateRequest')
  ->once();

不幸的是,您无法拦截非公共方法。这是单元测试的一部分,因此应该 运行 正确。如果你想拦截该方法中的部分逻辑,你应该考虑将其重构为服务 class 然后你可以这样调用它:

public function myMethod($request)
{
   app(RequestService::class)->validateRequest($request);
   $response = App\ModelClass::doSomething();
   return response()->json($response)
}

然后你可以像这样模拟它:

App::shouldReceive('make->validateRequest') (...)