为什么在进行集成测试时必须重新加载Auth::user() ?



这是关于如何在Laravel集成测试中等待页面重新加载的后续文章

我正在做的是编辑用户的配置文件,然后重新显示视图。

我的配置文件操作:(UserController)

public function profile(){
    return view('user/profile');
}

视图包含如下代码

{{ Auth::user()->firstname }}

现在在我的测试中,显示旧的(未更改的)用户数据。

测试:

protected function editUserProfile()
{
    $this->visit('/user/profile');
    $firstName = $this->faker->firstname;
    $lastname = $this->faker->lastname;
    $this->within('#userEditForm', function() use ($firstName, $lastname) {
        $this->type($firstName, 'firstname');
        $this->type($lastname, 'surname');
        $this->press('Save')
            ->seePageIs('/user/profile')
            ->see($firstName)   # here the test fails
            ->see($lastname);
    });
}

当我像这样改变UserController时:

public function profile(){
    Auth::setUser(Auth::user()->fresh());
    return view('user/profile');
}

一切正常

现在我想知道,为什么会这样。

在这种情况下,为什么集成测试对浏览器的行为不同?是否有更好的方法来调整这种行为,以便只有在存在"真正的问题"时测试才会失败?还是我的代码很糟糕?

您可能在请求中使用update (int $uid) ?

最可能的解释是Laravel在测试期间只使用一个应用程序实例。它接受你给它的输入,建立一个请求对象,然后把它发送给控制器功能。从这里,它可以渲染视图,并检查它是否包含您的文本。

在身份验证实现中,一旦调用Auth::user(),它会做两件事之一:

  • 如果没有用户被加载,它尝试从存储中检索它。
  • 如果一个用户已经加载,它返回它。

你的更新方法(我猜)是从存储中检索用户的新实例并更新它,而不是缓存的一个。

例如:

Auth::loginUsingId(1234);
Auth::user()->email; // 'user@example.com'
$user = AppUser::find(1234);
$user->email; // 'user@example.com';
$user->update(['email' => 'user2@example.com']);
$user->email; // 'user2@example.com'
Auth::user()->email; // 'user@example.com'

最新更新