Laravel 测试通过了身份验证中间件,但未通过数据提供程序 Auth::user()
Laravel test passes auth middleware but fails Auth::user() with data providers
我正在使用集成的 PHPUnit 配置测试我的 Laravel 应用程序,我在测试中遇到用户身份验证问题。
我有这个测试(缩短)
public function testShowEditForm($user, $expectedStatus, $expectedLocation, $expectedSee, $expectedDontSee) {
if ($user !== null)
$this->actingAs($user);
// $this->assertAuthenticatedAs($user); -> This is true!
$response = $this->get("/objects/edit/");
$response->assertStatus($expectedStatus);
// [...]
}
与此数据提供者:
public function showEditFormProvider() {
return [
'allowedUser' => [
UserGenerator::getControllingUser(),
200,
null,
["something"],
[]
]
];
}
UserGenerator::getControllingUser()
仅触发用户工厂,添加一些权限和 returns 用户对象。
测试方法(也缩短):
public function edit($object_id = null) {
$user = User::find(Auth::user()->id); // Auth::user() returns null
// [...]
}
此方法的路由封装在 routes/web.php
的 "middleware" => "auth"
部分内
问题:
数据提供者被正确调用,它通过中间件但是Auth::user()
在edit()
方法中调用returns null - 所以无论是否通过中间件,身份验证似乎都失败了?
- 如果我直接替换testShowEditForm中的参数$user
使用 UserGenerator::getControllingUser(),它可以工作(但这不是
很好的解决方法,因为我有很多测试用例,所以我需要
数据提供者)。
- 所以我通过调用数据提供者来解决
$this->showEditFormProvider() 在测试方法的第一行
testShowEditForm() - 但它被调用了两次(正确的是什么
根据此 1)的行为。但这也不是
理想的解决方法,因为如果我在提供程序中创建一个对象
测试,它也被创建了两次,所以断言失败了。
我做错了什么吗?我已经为这个主题搜索了很多,测试方法中的 actingAs()
/be()
方法似乎是模拟登录用户的最佳实践。
1 "All data providers are executed before both the call to the setUpBeforeClass static method and the first call to the setUp method." https://phpunit.de/manual/3.7/en/writing-tests-for-phpunit.html
在Laravel 5.8中使用
$user = User::find(Auth::id());
而不是
$user = User::find(Auth::user()->id); // Auth::user() returns null
在控制器内部。
我不知道为什么,但也许它会在未来帮助一些搜索开发人员。
有趣的是,自从 Laravel 6(目前我的应用程序在 6.10.0 上),没有更多问题,即使是 "old" 实现。
我正在使用集成的 PHPUnit 配置测试我的 Laravel 应用程序,我在测试中遇到用户身份验证问题。
我有这个测试(缩短)
public function testShowEditForm($user, $expectedStatus, $expectedLocation, $expectedSee, $expectedDontSee) {
if ($user !== null)
$this->actingAs($user);
// $this->assertAuthenticatedAs($user); -> This is true!
$response = $this->get("/objects/edit/");
$response->assertStatus($expectedStatus);
// [...]
}
与此数据提供者:
public function showEditFormProvider() {
return [
'allowedUser' => [
UserGenerator::getControllingUser(),
200,
null,
["something"],
[]
]
];
}
UserGenerator::getControllingUser()
仅触发用户工厂,添加一些权限和 returns 用户对象。
测试方法(也缩短):
public function edit($object_id = null) {
$user = User::find(Auth::user()->id); // Auth::user() returns null
// [...]
}
此方法的路由封装在 routes/web.php
的"middleware" => "auth"
部分内
问题:
数据提供者被正确调用,它通过中间件但是Auth::user()
在edit()
方法中调用returns null - 所以无论是否通过中间件,身份验证似乎都失败了?
- 如果我直接替换testShowEditForm中的参数$user 使用 UserGenerator::getControllingUser(),它可以工作(但这不是 很好的解决方法,因为我有很多测试用例,所以我需要 数据提供者)。
- 所以我通过调用数据提供者来解决 $this->showEditFormProvider() 在测试方法的第一行 testShowEditForm() - 但它被调用了两次(正确的是什么 根据此 1)的行为。但这也不是 理想的解决方法,因为如果我在提供程序中创建一个对象 测试,它也被创建了两次,所以断言失败了。
我做错了什么吗?我已经为这个主题搜索了很多,测试方法中的 actingAs()
/be()
方法似乎是模拟登录用户的最佳实践。
1 "All data providers are executed before both the call to the setUpBeforeClass static method and the first call to the setUp method." https://phpunit.de/manual/3.7/en/writing-tests-for-phpunit.html
在Laravel 5.8中使用
$user = User::find(Auth::id());
而不是
$user = User::find(Auth::user()->id); // Auth::user() returns null
在控制器内部。 我不知道为什么,但也许它会在未来帮助一些搜索开发人员。 有趣的是,自从 Laravel 6(目前我的应用程序在 6.10.0 上),没有更多问题,即使是 "old" 实现。