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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (57)

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

所以在TestCase中我们使用:

use WithoutMiddleware;

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

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

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

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

提问于
用户回答回答于

我发现这样做的最好方法不是使用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,完全禁用该功能。

用户回答回答于

Laravel>=5.5

到了拉勒维尔5.5,withoutMiddleware()方法允许您指定要禁用的中间件,而不是禁用它们。因此,与其修改所有中间件以添加env检查,不如在测试中这样做:

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

拉腊维尔<5.5

如果您在Laravel<5.5上,可以通过将更新后的方法添加到基本TestCase类来覆盖框架TestCase中的功能来实现相同的功能。

PHP>=7

如果您在PHP 7+上,将以下内容添加到TestCase类中,那么您将能够使用上面提到的相同的方法调用。此功能使用一个匿名类,它是在PHP 7中引入的。

/**
 * 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<7

如果使用PHP<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;
}

扫码关注云+社区

领取腾讯云代金券