Middleware — это очень удобный инструмент Laravel для фильтрации запросов и выполнения других функций. Возникает вопрос, как убедиться, что middleware работает правильно. В данной статье я расскажу, как можно протестировать middleware.
Unit тесты
Первое, что приходит на ум, это unit-тесты. Но проблема в том, что unit-тест не проверяет, действительно ли middleware активно и вы не знаете, как оно поведет себя вместе с другими middleware в вашем приложении.
Интеграционные тесты
Использование интеграционных тестов для конкретных url в приложении решает часть проблем с unit-тестами, но при этом становится сложнее протестировать поведение самого middleware.
Тесты middleware
При написании тестов нам необходимо убедиться, что middleware работает так, как ожидается, и что middleware активно для определенных запросов.
Рассмотрим следующий пример:
<?php namespace Tests\Unit; use App\Http\Middleware\TrimStrings; use Illuminate\Foundation\Testing\TestResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use Tests\TestCase; class MiddlewareTest extends TestCase { public function testMiddleware() { Route::middleware(TrimStrings::class)->group(function () { Route::post('trim-strings-test', function (Request $request) { return response()->json([ 'string' => $request->post('string'), ]); }); }); tap( $this->post('trim-strings-test', ['string' => ' bar ']), function (TestResponse $response) { $this->assertEquals('bar', $response->json()['string']); } ); } }
Чтобы протестировать middleware (в данном примере я использую TrimStrings, который включен в Laravel), создается тестовый маршрут, для которого мы указываем тестируемый middleware, как мы используем их в самом приложении. Это позволяет проверить, что middleware действительно настроено и работает правильно.
Но как проверить, что middleware действительно активны там, где это нужно? Рассмотрим следующий пример. Добавим в файл с маршрутами следующий код:
Route::middleware(\App\Http\Middleware\TrimStrings::class)->group(function () { Route::post('test-middleware', function (Request $request) {}) ->name('test-middleware'); });
Код проверки, что middleware действительно активен для маршрута будет выглядить так:
<?php namespace Tests\Unit; use App\Http\Middleware\TrimStrings; use Illuminate\Support\Facades\Route; use Tests\TestCase; class MiddlewareActiveTest extends TestCase { public function testRouteHasMiddleware() { $this->assertArrayHasKey( TrimStrings::class, array_flip(Route::getRoutes()->getByName('test-middleware')->gatherMiddleware()) ); } }
В данном случае, для каждого маршрута, или группы маршрутов, которые нужно проверить, мы получаем массив middleware и проверяем, что он содержит нужный нам класс.
Код из этой статьи можно скачать с GitHub: https://github.com/RusinovIG/blog-examples/pull/2 и запустить локально.
Заключение
Мы рассмотрели, как можно просто и удобно протестировать корректность работы middleware, а так же проверить, что они действительно применяются к нужным маршрутам. Такая проверка может быть особенно полезной, чтобы убедиться, что все маршруты вашего api защищены, если вы используете middleware для проверки прав доступа.