使用工厂和确定性种子在Laravel中播种测试数据库

时间:2018-11-02 12:00:17

标签: laravel faker laravel-seeding

我有许多工厂根据文档中的建议使用造假者生成模型:

$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种子?

还是无法通过最佳实践在测试中设置数据库状态(我想使用工厂,但这可能不是最佳方法)?

1 个答案:

答案 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不变。