In Laravel 7 we pretty routinely use the pattern:
public function provideCanDoThing(): array
{
return [
"Root can do thing" => [['root'], true],
"Normal user cannot do thing" => [[], false],
"Root cannot do thing while suspended" => [['root', 'suspended'], false],
];
}
/**
* @dataProvider provideCanDoThing
*/
public function testCanDoThing(array $userStates, bool $expectedCanDo): void
{
$user = factory(User::class)->states($userStates)->create();
self::expectSame($expectedCanDo, $user->canDoThing());
}
The state "root" can be pretty complicated, with a combo of attributes and afterCreating
logic.
In new Laravel 8 factories, the state
method no longer runs the collected changes in a named state, instead it... works just like passing attributes to make
or create
?
I can see how I could rewrite the test more like
$userFactory = User::factory();
foreach($userStates as $userState){
$userFactory = $userFactory->{$userState}();
}
$user = $userFactory->create();
But that seems much less expressive. I guess I'm surprised I can't find a method on Factory
that does that for me.
question from:
https://stackoverflow.com/questions/65851381/laravel-8-factory-state-from-a-unit-test-data-provider-porting-from-laravel-7 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…