如何在Laravel测试中禁用选定的中间件

sur*_*190 13 php laravel

因此,运行时出现Authentication和CSRF的错误是很常见的phpunit.

所以在TestCase中我们使用:

use WithoutMiddleware;

这个问题是当表单失败时,它通常会返回Flash消息和旧输入.我们已禁用所有中间件,因此我们无法访问Input::old('username');或闪存消息.

此外,我们对此失败表单的测试返回:

Caused by
exception 'RuntimeException' with message 'Session store not set on request.
Run Code Online (Sandbox Code Playgroud)

有没有办法启用会话中间件并禁用其他所有内容.

Eni*_*jar 22

我发现这样做的最好方法不是使用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);
}
Run Code Online (Sandbox Code Playgroud)

这将覆盖其中的handle方法Illuminate\Foundation\Http\Middleware\VerifyCsrfToken,完全禁用该功能.

  • 很好的解决方案,易于阅读和理解.顺便说一下,`env('APP_ENV')`可以替换为`app() - > env`,这有点好点:) (3认同)
  • 而不是直接检查`env('APP_ENV')`你可以使用`app() - > runningUnitTests()`(内部将执行相同的评估,但如果env值将来发生变化,它仍然可以工作). (3认同)

pat*_*cus 16

Laravel >= 5.5

从 Laravel 5.5 开始,该withoutMiddleware()方法允许您指定要禁用的中间件,而不是将它们全部禁用。因此,无需修改所有中间件以添加 env 检查,您只需在测试中执行以下操作:

$this->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class);
Run Code Online (Sandbox Code Playgroud)

Laravel < 5.5

如果您使用的是 Laravel < 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;
}
Run Code Online (Sandbox Code Playgroud)

PHP < 7

如果您使用的是 PHP < 7,则必须创建一个实际的类文件,并将其注入容器而不是匿名类。

在某处创建这个类:

class FakeMiddleware
{
    public function handle($request, $next)
    {
        return $next($request);
    }
}
Run Code Online (Sandbox Code Playgroud)

覆盖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;
}
Run Code Online (Sandbox Code Playgroud)

  • 尽管我在测试中添加了“$this-&gt;withoutMiddleware('friend-alias-name');”,但我还是浪费了 30 分钟的时间试图找出为什么该特定中间件仍在运行。结果你_have_使用中间件类名而不是友好的别名。 (3认同)