Прежде всего, я знаю docs:
Примечание. Вы не должны высмеивать фасад запроса. Вместо этого передайте требуемый вход в HTTP-вспомогательные методы, такие как вызов и сообщение при выполнении теста.
Но эти тесты больше похожи на интеграцию или функциональность, поскольку, несмотря на то, что вы тестируете контроллер (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
}
Это работает отлично, и они следуют стилю Arrange, Act, Assert.
Проблема заключается в 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 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 с помощью Unit Tests на основе Laravel, поскольку, похоже, документация ориентирована на интеграционное тестирование путем взаимодействия взаимодействия между зависимостями и SUT с помощью $this->call()
?