Заполнение тестовой базы данных в Laravel с использованием фабрик и детерминированных семян - PullRequest
0 голосов
/ 02 ноября 2018

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

$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 из тестового примера?

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

1 Ответ

0 голосов
/ 02 ноября 2018

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 остается без изменений.

...