我有许多工厂根据文档中的建议使用造假者生成模型:
$factory->define(App\Member::class, function (Faker $faker) {
return [
'name' => $faker->name()
];
});
我想在测试中使用这些工厂,以便将数据库设置为已知状态。当我调用factory(\App\Member::class, 10)
时,Faker(根据其性质)正在创建随机数据,这会使诸如$this->assertEquals('Eve', Member::find(5)->name)
之类的断言在以后的运行中失败。
我注意到Faker有一种seed
方法来允许确定性的数据生成:
$faker = Faker\Factory::create();
$faker->seed(1234);
但是,使用factory(\App\Member::class, 10)
接口似乎无法设置工厂中使用的Faker实例的种子。
是否可以通过测试用例设置Faker种子?
还是无法通过最佳实践在测试中设置数据库状态(我想使用工厂,但这可能不是最佳方法)?
答案 0 :(得分:1)
Faker与您的工厂一起使用是为了允许您快速创建模型实例,而不必在测试中自行提供所有数据。简单地做起来容易得多:
factory(User::class)->create();
...比手动指定User
模型所需的所有字段要多得多。 Faker提供了工厂定义中指定的所有字段的随机样本数据。
在测试中进行断言时,您不应该依赖于提前知道随机数据将是什么。您可以自己提供属性,这些属性将合并到工厂中定义的随机数据中,并可以使用此数据进行断言。
一个简单的小例子:
$user = factory(User::class)->create(['name' => 'Joe Bloggs']);
$this->assertEquals('Joe Bloggs', $user->name);
这样做的好处是您只需要提供您感兴趣的测试属性,就可以让工厂负责提供其余数据。
您当然可以允许工厂提供属性,然后在生成的模型中使用该信息来检查数据库中的数据。像这样:
$user = factory(User::class)->create(['enabled' => false]);
$user->enableUser();
$this->seeInDatabase((new User)->getTable(), [
'id' => $user->id,
'name' => $user->name,
'enabled' => true
]);
在此示例中,工厂用于创建用户,并将enabled
属性设置为false
。您正在测试的方法(在本例中为enableUser
)正在运行。然后,您可以在where
的{{1}}部分中使用工厂生成的用户名和用户名,以及seeInDatabase
来确保为生成的用户更新了数据库,通过将'enabled' => true
字段设置为enabled
,但保持生成的true
不变。