В современном веб‑разработке тестирование middleware становится ключевым этапом обеспечения надёжности и безопасности приложений. Особенно актуально это при работе с Yii2 2.0.40, где middleware реализует промежуточную логику, от проверки авторизации до логирования запросов. В этой статье мы разберём, как тестировать пользовательский middleware в Yii2 2.0.40, используя PHPUnit, мокировать запросы и ответы, а также проверять редиректы. Пошаговый пример поможет быстро внедрить QA‑процессы в ваш проект без лишних усилий.

Разбор задачи

Предположим, у нас есть middleware, который проверяет наличие токена в заголовке запроса и при его отсутствии перенаправляет пользователя на страницу логина. Тестируемая логика должна обрабатывать два сценария: корректный токен – запрос проходит дальше, токен отсутствует – генерируется редирект. Для проверки нам понадобится создать mock‑объекты запроса и ответа, а также убедиться, что middleware корректно взаимодействует с компонентом Yii::$app->response.

Пошаговое решение

1. Создаём класс теста, наследуемый от PHPUnitFrameworkTestCase. Внутри определяем метод setUp(), где инициализируем приложение Yii2 в режиме тестирования, подключаем необходимые компоненты и создаём экземпляр middleware. 2. Для mock‑объекта запроса используем Yii::$app->createRequest() и подменяем заголовки, чтобы симулировать наличие или отсутствие токена. 3. Мокаем объект ответа через PHPUnit’s createMock, чтобы перехватить вызовы setStatusCode, redirect и getHeaders. 4. В первом тесте передаём запрос с валидным токеном, вызываем middleware и проверяем, что статус ответа остаётся 200, а редирект не был вызван. 5. Во втором тесте отправляем запрос без токена, проверяем, что метод redirect был вызван с URL логина, а статус кода установлен в 302. 6. Для проверки редиректа используем assertion containsHeader(‘Location’, ‘/login’) и убедимся, что middleware правильно редиректит пользователя. 7. После выполнения каждого теста очищаем состояние приложения, чтобы избежать конфликтов между тестами. В результате вы получите надёжный набор unit‑тестов, покрывающих критические пути вашего middleware.

Рабочий код

headers->set('X-Middleware', 'Applied');
        return $response;
    }
}

class MiddlewareTest extends TestCase
{
    public function testMiddlewareAddsHeader()
    {
        // Создаём имитацию приложения
        $app = new Application(['id' => 'test-app']);

        // Mock запроса
        $request = new Request();
        $request->setPathInfo('/test');

        // Mock ответа
        $response = new Response();

        // Регистрируем middleware
        $app->on(Application::EVENT_BEFORE_REQUEST, function ($event) {
            $event->request->middleware = new SampleMiddleware();
        });

        // Запускаем middleware вручную
        $middleware = new SampleMiddleware();
        $res = $middleware->handle($request, function () use ($response) {
            return $response;
        });

        // Проверяем наличие заголовка
        $this->assertEquals('Applied', $res->headers->get('X-Middleware'));
    }
}

Типичные ошибки

  • Неправильный порядок регистрации middleware – он должен добавляться до обработки запроса.
  • Отсутствие mock‑объектов – без имитации Request и Response тест не увидит изменения.
  • Использование $app->run() в тесте – это вызывает реальный цикл, а не unit‑тест.
  • Неправильный тип callback – вместо функции должен быть объект Response.

FAQ

Как mock‑ить Request и Response?

Используйте классы yiiwebRequest и yiiwebResponse, но не инстанцируйте напрямую через Yii::$app. Создайте объекты вручную, задав pathInfo и необходимые заголовки.

Можно ли тестировать middleware без приложения?

Да, но нужно передавать в handle() настоящий Request и функцию‑замыкание, возвращающую Response. Это избавит от зависимости от глобального $app.

Что делать, если middleware зависит от компонентов (Redis, DB)?

Создайте mock‑компоненты и установите их в $app->components, либо используйте dependency injection через конструктор. В тесте мокайте только нужные методы.

Заключение

Тестирование middleware в Yii2 2.0.40 с PHPUnit – это просто, если следовать шагам: mock‑ить Request/Response, регистрировать middleware вручную, проверять изменения. Ниже чек‑лист.

  • Создать новый тестовый класс, расширяющий PHPUnitFrameworkTestCase.
  • Инициализировать Request и Response без использования Yii::$app.
  • Регистрировать middleware через событие или напрямую в handle().
  • Использовать замыкание, возвращающее Response.
  • Проверять изменённые заголовки, статус, тело и др.
  • Отделять unit‑тесты от интеграционных – не использовать $app->run().

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *