Тестирование middleware в Laravel

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 для проверки прав доступа.

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.