【问题标题】:Feature test actingas effects all guards?功能测试代理会影响所有警卫吗?
【发布时间】:2020-01-13 22:46:00
【问题描述】:

我的应用程序中有两个不同的用户对象,一个 App\User 和一个 App\Admin。对于两者,我有不同的身份验证保护。

我的默认保护是web 模型App\User 保护,我也有一个admin 模型App\Admin 保护。

比如这段代码

  $admin = factory(\App\Admin::class)->make();
  \Auth::guard('admin')->login($admin);

  dd([\Auth::check(), \Auth::guard('admin')->check()]);

返回

[假,真]

正如预期的那样。

但是,在我的功能测试中,我正在这样做:

$admin = factory(\App\Admin::class)->make();
$response = $this->actingAs($admin, 'admin')
                 ->get('/admin');
dd([\Auth::check(), \Auth::guard('admin')->check()]);

由于某种原因返回

[真,真]

这会导致各种错误(例如,我有一个普通用户的日志中间件,并且尝试将管理员存储为普通用户会引发 foreign_key 异常等)。

为什么actingAs 启用两个守卫?这是 Laravel 5.6 中的错误还是我做错了什么?

【问题讨论】:

    标签: php laravel-5 phpunit


    【解决方案1】:

    当你调用 actingAs 方法时,Laravel 在内部将默认保护更改为 admin(在这种情况下)。

    请使用下面的代码

    $defaultGuard = config('auth.defaults.guard');
    
    $admin = factory(\App\Admin::class)->make();
    $this->actingAs($admin, 'admin');
    \Auth::shouldUse($defaultGuard);
    
    $response = $this->get('/admin');
    
    dd([\Auth::check(), \Auth::guard('admin')->check()]);
    

    你也可以在TestCase类中提取一个方法actingAsAdmin,这样你就可以复用这个函数了。

    public function actingAsAdmin($admin) {
        $defaultGuard = config('auth.defaults.guard');
        $this->actingAs($admin, 'admin');
        \Auth::shouldUse($defaultGuard);
    
        return $this;
    }
    

    然后像下面这样调用这个函数。

    $admin = factory(\App\Admin::class)->make();
    $response = $this->actingAsAdmin($admin)->get('/admin');
    dd([\Auth::check(), \Auth::guard('admin')->check()]);
    

    【讨论】:

    • 第二种方案看起来不错,但是\Auth::shouldUse 并没有改变函数外的默认守卫。如果在调用actingAsAdmin 之后输出config('auth.defaults.guard'),那么它将是非默认保护。
    • 我注意到它是因为在创建两个 get 响应时都使用 actingAsAdmin
    猜你喜欢
    • 2013-06-05
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    相关资源
    最近更新 更多