Размышления об уникальности в фабриках
Как много уникальности вам нужно?
Некоторые участники сообщества Mastering Laravel столкнулись с проблемой, связанной с фабриками, когда время от времени создавались две модели с одинаковым значением свойства, что приводило к сбоям в работе тестов.
Возник вопрос: как предотвратить подобные случайные сбои в тестировании?
Короткий ответ — использовать модификатор unique()
, предоставляемый `Faker
, для предотвращения совпадения этих значений, но есть и более тонкий подход, которым я хочу поделиться.
Рассмотрим на конкретном примере, чтобы было понятнее. У нас есть модель `User
со свойствами first_name
и last_name
.
И только в одном или двух тестах требуется убедиться, что фабрика генерирует уникальные значения для этих свойств.
Не рекомендую использовать цепочку unique()
для этих свойств в определении фабрики по умолчанию. Почему? Уникальность нужна только нескольким тестам, а добавление этого модификатора добавляет накладные расходы при каждом использовании.
Я бы добавил unique()
в определение по умолчанию только в том случае, если схема базы данных требует уникальности. Тогда это основное требование приложения.
Так что же можно сделать вместо этого? Если это всего лишь один или два теста, я бы сделал это прямо внутри теста при вызове фабрики:
User::factory()->create([ 'first_name' => $this->faker->unique()->firstName, 'last_name' => $this->faker->unique()->lastName, ]);
Если это необходимо более чем в паре тестов, можно пойти дальше и создать новое состояние в фабрике:
// в UserFactory.php public function uniqueNames() { return $this->state([ 'first_name' => $this->faker->unique()->firstName, 'last_name' => $this->faker->unique()->lastName, ]); } // затем в тесте User::factory()->uniqueNames()->create();