Laravel 测试中如何在一次测试中注销?

Jak*_*pov 5 unit-testing laravel

Laravel v5.7.1

我有多个具有相同断言的测试,并且希望将它们移动到一个函数中并从测试中调用它。这是函数的示例:

private function admin_only($url, $method = 'GET', $data = []) {
    // \Auth::logout();
    $response = $this->json($method, $url, $data);
    $response->assertStatus(401);
    $response = $this->actingAs($this->user(),'api')->json($method, $url, $data);
    $response->assertStatus(403);

    $response = $this->actingAs($this->admin(),'api')->json($method, $url, $data);
    $response->assertStatus(200);
}
Run Code Online (Sandbox Code Playgroud)

在这里,我首先检查未经身份验证的用户,一切都按预期工作,但是有一些函数,API 调用会切换某些状态,所以我想通过第二次调用函数来将其恢复:

$this->admin_only('/api/service/toggle-state', 'POST', $data);
$this->admin_only('/api/service/toggle-state', 'POST', $data);
Run Code Online (Sandbox Code Playgroud)

同一测试中的第二次调用会导致失败,因为第一次$this->json()用作管理员并返回成功代码。

\Auth::logout()应该可以解决问题,但却引发错误BadMethodCallException: Method Illuminate\Auth\RequestGuard::logout does not exist.

“对第二次呼叫进行单独测试”、“无切换恢复”、“非管理员用户和访客使用相同的响应代码”等解决方案应该有效,但对我来说似乎是错误的。

Dam*_*nov 7

幸运的RequestGuardMacroable,我们可以用我们自己的方法来扩展它。尝试执行以下操作:

use Illuminate\Auth\RequestGuard;

// ...

RequestGuard::macro('logout', function() {
    $this->user = null;
});

$this->app['auth']->guard('api')->logout(); // or omit `->guard('api')` part
Run Code Online (Sandbox Code Playgroud)

这与事实相反->actingAs。以下所有请求都不会包含经过身份验证的用户。

这可以作为方法添加到基测试类中,然后用作$this->actingAsGuest()或类似的东西。不管怎样,在 Laravel 中默认使用这个会很方便。


小智 0

你可能有不同的守卫>>所以这可能有用

Auth::guard('admin')->logout();
Run Code Online (Sandbox Code Playgroud)

你可以将“admin”更改为任何守卫名称