Размышления об уникальности в фабриках
Как много уникальности вам нужно?
Некоторые участники сообщества 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();