{{TOC}} {{DOCVER 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51}} == Введение == При тестирование Laravel-приложений иногда нужно "заглушить" некоторые части приложения, чтобы во время тестирования они на самом деле не работали. Например, при тестировании контроллера, создающего события, можно заглушить слушателей событий, чтобы они не выполнились во время теста. Это позволит вам протестировать только HTTP-отклик контроллера, не беспокоясь о выполнении слушателей событий, которые можно протестировать отдельно. В Laravel изначально есть вспомогательные функции для создания заглушек событий, задач и фасадов. Эти функции в основном обеспечивают удобную прослойку над Mockery, поэтому вам не надо делать вызовы сложных методов Mockery вручную. Само собой вы также можете сами создавать заглушки или шпионов с помощью ((http://docs.mockery.io/en/latest/ Mockery)) или PHPUnit. == События == === Использование заглушек === Если вы активно используете систему событий Laravel, вам может понадобиться приглушить или заглушить некоторые события при тестировании. Например, когда вы тестируете регистрацию пользователя, вы можете отключить запуск некоторых обработчиков события %%(t)UserRegistered%%, потому что слушатели могут отправить e-mail с "приветствием" и т.п. Laravel предоставляет удобный метод %%expectsEvents()%%, который проверяет возникновение ожидаемых событий, но предотвращает запуск любых слушателей этих событий: %% expectsEvents(UserRegistered::class); // Тестирование регистрации пользователя... } } %% Используйте метод %%doesntExpectEvents()%%, чтобы проверить, что указанные события не возникли: %% expectsEvents(OrderShipped::class); $this->doesntExpectEvents(OrderFailedToShip::class); // Тестирование доставки заказа... } } %% Если вы хотите предотвратить запуск всех слушателей событий, используйте метод %%withoutEvents()%%. При вызове этого метода все слушатели для всех событий будут заглушены: %% withoutEvents(); // Код тестирования регистрации пользователя... } } %% === Использование подделок === В качестве альтернативы заглушкам вы можете использовать метод %%fake()%% фасада %%(t)Event%% для предотвращения запуска всех слушателей событий. Затем вы можете проверить, что события возникли, и даже изучить данные, которые они получили. При использовании подделок проверки делаются после выполнения тестируемого кода: %% order->id === $order->id; }); Event::assertNotFired(OrderFailedToShip::class); } } %% == Задачи == === Использование заглушек === Иногда возникает необходимость протестировать то, что при поступлении запросов в ваше приложение вызывается определённая задача. Это позволит вам тестировать ваши маршруты и контроллеры изолированно, не беспокоясь о логике вашей задачи. Разумеется, затем вам надо протестировать задачу отдельным тест-кейсом. Laravel предоставляет удобный метод %%expectsJobs()%%, который проверяет, что ожидаемые задачи были вызваны. Но при этом сама задача не будет выполнена: %% expectsJobs(ShipOrder::class); // Тестирование доставки заказа... } } %% .(alert) Этот метод обнаруживает только те задачи, которые вызываются через методы типажа %%(t)DispatchesJobs%% или вспомогательную функцию %%dispatch()%%. Он не обнаруживает задачи в очереди, отправленные напрямую в %%Queue::push()%%. Как и в случае с заглушками событий, вы можете также проверить, что задача не была запущена, методом %%doesntExpectJobs()%%: %% doesntExpectJobs(ShipOrder::class); // Тестирование отмены заказа... } } %% Или же вы можете игнорировать все вызванные задачи, используя метод %%withoutJobs()%%. Этот метод вызывается в методе теста, и все задачи, вызванные во время теста, будут отменены: %% withoutJobs(); // Тестирование отмены заказа... } } %% === Использование подделок === В качестве альтернативы заглушкам вы можете использовать метод %%fake()%% фасада %%(t)Queue%% для предотвращения постановки задач в очередь. Затем вы можете проверить, что задачи были поставлены в очередь и даже исследовать полученные ими данные. При использовании подделок проверки делаются после выполнения тестируемого кода: %% order->id === $order->id; }); // Проверка того, что задача была поставлена в данную очередь... Queue::assertPushedOn('queue-name', ShipOrder::class); // Проверка того, что задача не была поставлена... Queue::assertNotPushed(AnotherJob::class); } } %% == Почтовые подделки == Вы можете использовать метод %%fake()%% фасада %%(t)Mail%% для предотвращения отправки писем. Затем вы можете проверить, что ((//docs/v5/mail почта)) была отправлена пользователям и даже исследовать переданные данные. При использовании подделок проверки делаются после выполнения тестируемого кода: %% order->id === $order->id; }); // Проверка того, что сообщение было отправлено данному пользователю... Mail::assertSentTo([$user], OrderShipped::class); // Проверка того, что сообщение не было отправлено... Mail::assertNotSent(AnotherMailable::class); } } %% == Подделки уведомлений == Вы можете использовать метод %%fake()%% фасада %%(t)Notification%% для предотвращения отправки уведомлений. Затем вы можете проверить, что ((//docs/v5/notifications уведомления)) были отправлены, и даже исследовать переданные им данные. При использовании подделок проверки делаются после выполнения тестируемого кода: %% order->id === $order->id; } ); // Проверка того, что уведомление было отправлено данным пользователям... Notification::assertSentTo( [$user], OrderShipped::class ); // Проверка того, что уведомление не было отправлено... Notification::assertNotSentTo( [$user], AnotherNotification::class ); } } %% == Фасады == В отличие от вызовов обычных статических методов ((//docs/v5/facades фасады)) могут быть заглушены. Это даёт большое преимущество над обычными статическими методами и предоставляет те же возможности для тестирования, что и внедрение зависимостей. При тестировании часто бывает необходимо заглушить вызов к фасаду Laravel в одном из ваших контроллеров. Например, рассмотрим такое действие контроллера: %% once() ->with('key') ->andReturn('value'); $this->visit('/users')->see('value'); } } %% .(alert) Вы не должны "заглушать" фасад %%(t)Request%%. Вместо этого передайте необходимые входные данные во вспомогательные методы HTTP, такие как %%call()%% и %%post()%%, при выполнении ваших тестов. А также вместо заглушки фасада %%(t)Config%% просто вызовите метод %%Config::set()%% в своём тесте.