logo
podcast Podcast
get help Get Unstuck

Thinking about uniqueness in factories

How much uniqueness do you need?

Joel Clermont
Joel Clermont
2025-01-28

Someone in the Mastering Laravel community was running into an issue with factories where every once in a while, two models would be created with the same value for a property, and this would lead to a flaky test failure.

The question was: how can we prevent these occasional test failures?

The short answer is to use the unique() modifier that Faker provides to prevent these values from colliding, but there's a more nuanced answer that I want to share.

Let's make it a tangible example, so we can discuss it more clearly. We have a User model with first_name and last_name properties.

And in only one or two tests, we need to make sure our factory generates unique values for those properties.

I would not recommend chaining unique() on those properties in the default factory definition. Why? Only a couple tests need uniqueness, and adding this modifier adds some overhead to every usage.

I'd only add unique() to the default definition if the database schema enforced uniqueness. Then it's a core application requirement.

So what would I do instead? If it's just one or two tests, I'd do it right inside the test when calling the factory:

User::factory()->create([
    'first_name' => $this->faker->unique()->firstName,
    'last_name' => $this->faker->unique()->lastName,
]);

If this is something needed in more than a handful of tests, I might go a step further and create a new state in my factory:

// in UserFactory.php
public function uniqueNames()
{
    return $this->state([
        'first_name' => $this->faker->unique()->firstName,
        'last_name' => $this->faker->unique()->lastName,
    ]);
}

// then in my test
User::factory()->uniqueNames()->create();

Here to help,

Joel

P.S. I bet you knew I was going to recommend that you should check out the Mastering Laravel community. Well, you should!

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice you can use.