Заполнение тестовой базы данных в Laravel с использованием фабрик и детерминированного начального числа

У меня есть несколько фабрик, генерирующих модели с использованием faker, как рекомендовано в документации:

$factory->define(App\Member::class, function (Faker $faker) {
    return [
        'name' => $faker->name()
    ];
});

Я хотел бы использовать эти фабрики в тестах, чтобы перевести базу данных в известное состояние. Faker (по своей природе) создает случайные данные, когда я вызываю factory(\App\Member::class, 10), что приводит к ошибке типа $this->assertEquals('Eve', Member::find(5)->name) при будущих запусках.

Замечу, что у Faker есть seed метод, позволяющий генерировать детерминированные данные:

$faker = Faker\Factory::create();
$faker->seed(1234);

Однако с интерфейсом factory(\App\Member::class, 10), похоже, нет способа установить начальное значение экземпляра Faker, используемого на заводе.

Есть ли способ установить начальное число Faker из тестового примера?

Или если это не удается, в лучших практиках для установки состояния базы данных в тесте (я хотел бы использовать фабрики, но, возможно, это не лучший подход)?


person thodic    schedule 02.11.2018    source источник


Ответы (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 части seeInDatabase вместе с 'enabled' => true, чтобы убедиться, что база данных была обновлена ​​для сгенерированного пользователя, установив в поле enabled значение true, но оставив сгенерированный name без изменений.

person Jonathon    schedule 02.11.2018