我使用LARAVEL 9和PHPSTAN
我有这个简单的测试方法:
public function createAndAuthenticatedAnUser(string $status = 'VALIDATED', bool $isAdmin = false): User
{
$user = User::factory()->create([
'status' => $status,
'is_admin' => $isAdmin
])->first();
$this->actingAs($user);
return $user;
}
当我运行PHPSTAN,我有这些错误:
40 Parameter #1 $user of method IlluminateFoundationTestingTestCase::actingAs() expects
IlluminateContractsAuthAuthenticatable, IlluminateDatabaseEloquentModel|null given.
41 Method TestsFeatureValidateRegistrationTest::createAndAuthenticatedAnUser() should return AppModelsUser
but returns IlluminateDatabaseEloquentModel|null.
第一个错误:actingAs
第二个错误:函数返回一个User(扩展了Authenticatable))
PHPSTAN的这段代码有什么问题?
首先不要运行PHPStan
进行单元测试,PHPStan
是检查类型完整性和它可以提供的其他静态分析。它们在单元测试中没有意义。
其次,你的工厂调用是错误的。如果没有提供计数,create()
只创建一个模型,这样返回它。如果count大于1,它将返回一个集合。
User::factory()->create([
'status' => $status,
'is_admin' => $isAdmin
])
当你调用first()时,它在单个用户查询生成器上调用它。返回Model或null。
这个问题与类型提示有关,是PHPStan
检查的,actingAs想要一个Authenticatable
,这是你的User类。PHPStan
唯一知道的是,你的第一次调用返回一个模型或null。这不是类型严格的,因此它会抱怨。正如Matias所指出的,所有问题都可以通过强制使用类型提示来解决,这在Laravel
的许多更通用的函数中都是需要的。
/** @var User $user */
$user = User::factory()->create([
'status' => $status,
'is_admin' => $isAdmin
]);