Может войдёшь?
Черновики Написать статью Профиль

Заглушки

перевод документация 5.х

  1. 1. Введение
  2. 2. События
    1. 2.1. Использование заглушек
    2. 2.2. Использование подделок
  3. 3. Задачи
    1. 3.1. Использование заглушек
    2. 3.2. Использование подделок
  4. 4. Почтовые подделки
  5. 5. Подделки уведомлений
  6. 6. Фасады
Этот перевод актуален для англоязычной документации на (ветка 5.3). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

При тестирование Laravel-приложений иногда нужно «заглушить» некоторые части приложения, чтобы во время тестирования они на самом деле не работали. Например, при тестировании контроллера, создающего события, можно заглушить слушателей событий, чтобы они не выполнились во время теста. Это позволит вам протестировать только HTTP-отклик контроллера, не беспокоясь о выполнении слушателей событий, которые можно протестировать отдельно.

В Laravel изначально есть вспомогательные функции для создания заглушек событий, задач и фасадов. Эти функции в основном обеспечивают удобную прослойку над Mockery, поэтому вам не надо делать вызовы сложных методов Mockery вручную. Само собой вы также можете сами создавать заглушки или шпионов с помощью Mockery или PHPUnit.

События

Использование заглушек

Если вы активно используете систему событий Laravel, вам может понадобиться приглушить или заглушить некоторые события при тестировании. Например, когда вы тестируете регистрацию пользователя, вы можете отключить запуск некоторых обработчиков события UserRegistered, потому что слушатели могут отправить e-mail с «приветствием» и т.п.

Laravel предоставляет удобный метод PHPexpectsEvents(), который проверяет возникновение ожидаемых событий, но предотвращает запуск любых слушателей этих событий:

PHP
<?php

use App\Events\UserRegistered;

class 
ExampleTest extends TestCase
{
  
/**
   * Тестирование регистрации нового пользователя.
   */
  
public function testUserRegistration()
  {
    
$this->expectsEvents(UserRegistered::class);

    
// Тестирование регистрации пользователя...
  
}
}

Используйте метод PHPdoesntExpectEvents(), чтобы проверить, что указанные события не возникли:

PHP
<?php

use App\Events\OrderShipped;
use 
App\Events\OrderFailedToShip;

class 
ExampleTest extends TestCase
{
  
/**
   * Тестирование доставки заказа.
   */
  
public function testOrderShipping()
  {
    
$this->expectsEvents(OrderShipped::class);
    
$this->doesntExpectEvents(OrderFailedToShip::class);

    
// Тестирование доставки заказа...
  
}
}

Если вы хотите предотвратить запуск всех слушателей событий, используйте метод PHPwithoutEvents(). При вызове этого метода все слушатели для всех событий будут заглушены:

PHP
<?php

class ExampleTest extends TestCase
{
  public function 
testUserRegistration()
  {
    
$this->withoutEvents();

    
// Код тестирования регистрации пользователя...
  
}
}

Использование подделок

В качестве альтернативы заглушкам вы можете использовать метод PHPfake() фасада Event для предотвращения запуска всех слушателей событий. Затем вы можете проверить, что события возникли, и даже изучить данные, которые они получили. При использовании подделок проверки делаются после выполнения тестируемого кода:

PHP
<?php

use App\Events\OrderShipped;
use 
App\Events\OrderFailedToShip;
use 
Illuminate\Support\Facades\Event;

class 
ExampleTest extends TestCase
{
  
/**
   * Тестирование доставки заказа.
   */
  
public function testOrderShipping()
  {
    
Event::fake();

    
// Выполнение доставки заказа...

    
Event::assertFired(OrderShipped::class, function ($e) use ($order) {
      return 
$e->order->id === $order->id;
    });

    
Event::assertNotFired(OrderFailedToShip::class);
  }
}

Задачи

Использование заглушек

Иногда возникает необходимость протестировать то, что при поступлении запросов в ваше приложение вызывается определённая задача. Это позволит вам тестировать ваши маршруты и контроллеры изолированно, не беспокоясь о логике вашей задачи. Разумеется, затем вам надо протестировать задачу отдельным тест-кейсом.

Laravel предоставляет удобный метод PHPexpectsJobs(), который проверяет, что ожидаемые задачи были вызваны. Но при этом сама задача не будет выполнена:

PHP
<?php

use App\Jobs\ShipOrder;

class 
ExampleTest extends TestCase
{
  public function 
testOrderShipping()
  {
    
$this->expectsJobs(ShipOrder::class);

    
// Тестирование доставки заказа...
  
}
}

Этот метод обнаруживает только те задачи, которые вызываются через методы типажа DispatchesJobs или вспомогательную функцию PHPdispatch(). Он не обнаруживает задачи в очереди, отправленные напрямую в PHPQueue::push().

Как и в случае с заглушками событий, вы можете также проверить, что задача не была запущена, методом PHPdoesntExpectJobs():

PHP
<?php

use App\Jobs\ShipOrder;

class 
ExampleTest extends TestCase
{
  
/**
   * Тестирование отмены заказа.
   */
  
public function testOrderCancellation()
  {
    
$this->doesntExpectJobs(ShipOrder::class);

    
// Тестирование отмены заказа...
  
}
}

Или же вы можете игнорировать все вызванные задачи, используя метод PHPwithoutJobs(). Этот метод вызывается в методе теста, и все задачи, вызванные во время теста, будут отменены:

PHP
<?php

use App\Jobs\ShipOrder;

class 
ExampleTest extends TestCase
{
  
/**
   * Тестирование отмены заказа.
   */
  
public function testOrderCancellation()
  {
    
$this->withoutJobs();

    
// Тестирование отмены заказа...
  
}
}

Использование подделок

В качестве альтернативы заглушкам вы можете использовать метод PHPfake() фасада Queue для предотвращения постановки задач в очередь. Затем вы можете проверить, что задачи были поставлены в очередь и даже исследовать полученные ими данные. При использовании подделок проверки делаются после выполнения тестируемого кода:

PHP
<?php

use App\Jobs\ShipOrder;
use 
Illuminate\Support\Facades\Queue;

class 
ExampleTest extends TestCase
{
  public function 
testOrderShipping()
  {
    
Queue::fake();

    
// Выполнение доставки заказа...

    
Queue::assertPushed(ShipOrder::class, function ($job) use ($order) {
      return 
$job->order->id === $order->id;
    });

    
// Проверка того, что задача была поставлена в данную очередь...
    
Queue::assertPushedOn('queue-name'ShipOrder::class);

    
// Проверка того, что задача не была поставлена...
    
Queue::assertNotPushed(AnotherJob::class);
  }
}

Почтовые подделки

Вы можете использовать метод PHPfake() фасада Mail для предотвращения отправки писем. Затем вы можете проверить, что почта была отправлена пользователям и даже исследовать переданные данные. При использовании подделок проверки делаются после выполнения тестируемого кода:

PHP
<?php

use App\Mail\OrderShipped;
use 
Illuminate\Support\Facades\Mail;

class 
ExampleTest extends TestCase
{
  public function 
testOrderShipping()
  {
    
Mail::fake();

    
// Выполнение доставки заказа...

    
Mail::assertSent(OrderShipped::class, function ($mail) use ($order) {
      return 
$mail->order->id === $order->id;
    });

    
// Проверка того, что сообщение было отправлено данному пользователю...
    
Mail::assertSentTo([$user], OrderShipped::class);

    
// Проверка того, что сообщение не было отправлено...
    
Mail::assertNotSent(AnotherMailable::class);
  }
}

Подделки уведомлений

Вы можете использовать метод PHPfake() фасада Notification для предотвращения отправки уведомлений. Затем вы можете проверить, что уведомления были отправлены, и даже исследовать переданные им данные. При использовании подделок проверки делаются после выполнения тестируемого кода:

PHP
<?php

use App\Notifications\OrderShipped;
use 
Illuminate\Support\Facades\Notification;

class 
ExampleTest extends TestCase
{
  public function 
testOrderShipping()
  {
    
Notification::fake();

    
// Выполнение доставки заказа...

    
Notification::assertSentTo(
      
$user,
      
OrderShipped::class,
      function (
$notification$channels) use ($order) {
        return 
$notification->order->id === $order->id;
      }
    );

    
// Проверка того, что уведомление было отправлено данным пользователям...
    
Notification::assertSentTo(
      [
$user], OrderShipped::class
    );

    
// Проверка того, что уведомление не было отправлено...
    
Notification::assertNotSentTo(
      [
$user], AnotherNotification::class
    );
  }
}

Фасады

В отличие от вызовов обычных статических методов фасады могут быть заглушены. Это даёт большое преимущество над обычными статическими методами и предоставляет те же возможности для тестирования, что и внедрение зависимостей. При тестировании часто бывает необходимо заглушить вызов к фасаду Laravel в одном из ваших контроллеров. Например, рассмотрим такое действие контроллера:

PHP
<?php

namespace App\Http\Controllers;

use 
Illuminate\Support\Facades\Cache;

class 
UserController extends Controller
{
  
/**
   * Показать список всех пользователей приложения.
   *
   * @return Response
   */
  
public function index()
  {
    
$value Cache::get('key');

    
//
  
}
}

Мы можем сделать заглушку вызова фасада Cache, используя метод PHPshouldReceive(), который вернёт экземпляр заглушки Mockery. Поскольку фасады на самом деле извлекаются и управляются сервис-контейнером Laravel, их намного проще тестировать, чем обычные статические классы. Например, давайте заглушим наш вызов метода PHPget() фасада Cache:

PHP
<?php

class FooTest extends TestCase
{
  public function 
testGetIndex()
  {
    
Cache::shouldReceive('get')
                ->
once()
                ->
with('key')
                ->
andReturn('value');

    
$this->visit('/users')->see('value');
  }
}

Вы не должны «заглушать» фасад Request. Вместо этого передайте необходимые входные данные во вспомогательные методы HTTP, такие как PHPcall() и PHPpost(), при выполнении ваших тестов. А также вместо заглушки фасада Config просто вызовите метод PHPConfig::set() в своём тесте.

Как вы считаете, полезен ли этот материал? Да Нет

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.