Прежде всего, мне известно, что в документах говорится:
Примечание: вы не должны имитировать фасад Request. Вместо этого передайте желаемый ввод во вспомогательные методы HTTP, такие как call и post, при запуске теста.
Но такие тесты больше похожи на интеграцию или функциональность, поскольку, даже если вы тестируете контроллер (SUT
), вы не отделение его от его зависимостей (Request
и другие, подробнее об этом позже).
Итак, то, что я делаю, чтобы выполнить правильный цикл TDD
, - это издеваться над Repository
, Response
и Request
(с которыми у меня проблемы).
Мой тест выглядит так:
public function test__it_shows_a_list_of_categories() {
$categories = [];
$this->repositoryMock->shouldReceive('getAll')
->withNoArgs()
->once()
->andReturn($categories);
Response::shouldReceive('view')
->once()
->with('categories.admin.index')
->andReturnSelf();
Response::shouldReceive('with')
->once()
->with('categories', $categories)
->andReturnSelf();
$this->sut->index();
// Assertions as mock expectations
}
Это прекрасно работает, и они следуют стилю Упорядочить, Действовать, Утвердить.
Проблема заключается в Request
, например в следующем:
public function test__it_stores_a_category() {
Redirect::shouldReceive('route')
->once()
->with('categories.admin.index')
->andReturnSelf();
Request::shouldReceive('only')
->once()
->with('name')
->andReturn(['name' => 'foo']);
$this->repositoryMock->shouldReceive('create')
->once()
->with(['name' => 'foo']);
// Laravel facades wont expose Mockery#getMock() so this is a hackz
// in order to pass mocked dependency to the controller's method
$this->sut->store(Request::getFacadeRoot());
// Assertions as mock expectations
}
Как видите, я высмеял Request::only('name')
звонок. Но когда я запускаю $ phpunit
, я получаю следующую ошибку:
BadMethodCallException: Method Mockery_3_Illuminate_Http_Request::setUserResolver() does not exist on this mock object
Поскольку я не вызываю setUserResolver()
напрямую из своего контроллера, это означает, что он вызывается напрямую реализацией Request
. Но почему? Я издевался над вызовом метода, он не должен вызывать никаких зависимостей.
Что я здесь делаю не так, почему я получаю это сообщение об ошибке?
PS: В качестве бонуса, я неправильно смотрю, заставляя TDD с модульными тестами на платформе Laravel, поскольку кажется, что документация ориентирована на интеграционное тестирование путем связывания взаимодействия между зависимостями и SUT с $this->call()
?
Request
и вам нужен простой запрос пути реального маршрута, тогда: вам не нужно имитировать запрос, вы можете просто создать запрос из маршрута и передать его, например:$myRequest = Request::create('/path/that/I_want', 'GET'); $this->assertTrue(functionUnderTest($myRequest));
- person Daryn   schedule 15.12.2020