Как отключить выбранное промежуточное ПО в тестах Laravel

Таким образом, при запуске phpunit возникают ошибки из Authentication и CSRF.

Итак, в TestCase мы используем:

use WithoutMiddleware;

Проблема с этим заключается в том, что когда формы терпят неудачу, они обычно возвращаются с помощью Flash Message и Old Input. Мы отключили все промежуточное ПО, поэтому у нас нет доступа к Input::old('username'); или флэш-сообщению.

Кроме того, наши тесты этого неудачного сообщения формы возвращаются:

Caused by
exception 'RuntimeException' with message 'Session store not set on request.

Есть ли способ включить промежуточное ПО Session и отключить все остальное.

Ответ 1

Лучшим способом, который я нашел для этого, является не использование признака WithoutMiddleware, а изменение промежуточного программного обеспечения, которое вы хотите отключить. Например, если вы хотите отключить функциональность промежуточного программного обеспечения VerifyCsrfToken в своих тестах, вы можете сделать следующее.

Внутри app/Http/Middleware/VerifyCsrfToken.php добавьте метод handle, который проверяет APP_ENV для тестирования.

public function handle($request, Closure $next)
{
    if (env('APP_ENV') === 'testing') {
        return $next($request);
    }

    return parent::handle($request, $next);
}

Это переопределит метод handle внутри Illuminate\Foundation\Http\Middleware\VerifyCsrfToken, полностью отключив функциональность.

Ответ 2

Вы можете использовать черту в тесте:

используйте Illuminate\Foundation\Testing\WithoutMiddleware;

Laravel> = 5,7

Ответ 3

Laravel> = 5,5

Начиная с Laravel 5.5, метод withoutMiddleware() позволяет вам указать промежуточное программное обеспечение, которое нужно отключить, вместо того, чтобы отключать их все. Таким образом, вместо изменения всего вашего промежуточного программного обеспечения для добавления проверок env, вы можете просто сделать это в своем тесте:

$this->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class);

Laravel & lt; 5.5

Если вы на Laravel & lt; 5.5, вы можете реализовать ту же функциональность, добавив обновленный метод в базовый класс TestCase, чтобы переопределить функциональность из среды TestCase.

PHP> = 7

Если вы используете PHP7+, добавьте следующее в ваш класс TestCase, и вы сможете использовать тот же вызов метода, который упомянут выше. Эта функциональность использует анонимный класс, который был представлен в PHP7.

/**
 * Disable middleware for the test.
 *
 * @param  string|array|null  $middleware
 * @return $this
 */
public function withoutMiddleware($middleware = null)
{
    if (is_null($middleware)) {
        $this->app->instance('middleware.disable', true);

        return $this;
    }

    foreach ((array) $middleware as $abstract) {
        $this->app->instance($abstract, new class {
            public function handle($request, $next)
            {
                return $next($request);
            }
        });
    }

    return $this;
}

PHP & lt; 7

Если вы используете PHP & lt; 7 вам нужно будет создать настоящий файл класса и вставить его в контейнер вместо анонимного класса.

Создайте этот класс где-нибудь:

class FakeMiddleware
{
    public function handle($request, $next)
    {
        return $next($request);
    }
}

Переопределите метод withoutMiddleware() в вашем TestCase и используйте свой класс FakeMiddleware:

/**
 * Disable middleware for the test.
 *
 * @param  string|array|null  $middleware
 * @return $this
 */
public function withoutMiddleware($middleware = null)
{
    if (is_null($middleware)) {
        $this->app->instance('middleware.disable', true);

        return $this;
    }

    foreach ((array) $middleware as $abstract) {
        $this->app->instance($abstract, new FakeMiddleware());
    }

    return $this;
}