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

Ale*_*lex 7 php testing router laravel

这是如何在Laravel集成测试中等待页面重新加载的后续内容

我正在做的是编辑用户的个人资料,然后重新显示视图.

我的个人资料操作:(UserController)

public function profile(){
    return view('user/profile');
}
Run Code Online (Sandbox Code Playgroud)

该视图包含类似的代码

{{ Auth::user()->firstname }}
Run Code Online (Sandbox Code Playgroud)

现在在我的测试期间,显示旧的(未更改的)用户数据.

考试:

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

当我像这样更改UserController时:

public function profile(){
    Auth::setUser(Auth::user()->fresh());
    return view('user/profile');
}
Run Code Online (Sandbox Code Playgroud)

一切正常.

现在我想明白,为什么会这样.

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

Stu*_*urm 1

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

最可能的解释是 Laravel 在测试期间仅使用单个应用程序实例。它接受您提供的输入,构建请求对象,然后将其发送到控制器方法。从这里它可以渲染视图并检查它是否包含您的文本。

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

  • 如果没有加载用户,它会尝试从存储中检索它。
  • 如果用户已加载,则返回该用户。

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

例如:

\Auth::loginUsingId(1234);
\Auth::user()->email; // 'user@example.com'

$user = \App\User::find(1234);
$user->email; // 'user@example.com';

$user->update(['email' => 'user2@example.com']);
$user->email; // 'user2@example.com'

\Auth::user()->email; // 'user@example.com'
Run Code Online (Sandbox Code Playgroud)