# UniqueGroupProvider for Faker
This provider is useful for creating entities where some property or combination of properties must be unique among all entities in the table.
By creating multiple entities without this provider and without setting unique properties (combinations of properties) manually for each entity, there is a risk that due to random generation of values, the next entity will receive the same value (or combination of values) as one of the already created entities, which will result in a unique constraint violation.
With the unique group generator you are guaranteed to never get the same combination of values within the same group in tests or fixtures.
# Example:
The ReferralCode
entity has the code
and status
fields. The status can be active
or inactive
. There can be 2 identical referral codes in the table, but only with different statuses (only one can be active
). Thus, we need a unique constraint on columns (code
, status
).
In the ReferralCodeFactory
we can use UniqueGroupProvider
like this:
protected function getDefaults(): array
{
return [
'code' => self::faker()
->uniqueGroup('referral-code-unique-group')
->word(),
'status' => self::faker()
->uniqueGroup('referral-code-unique-group')
->randomElement(ReferralCode::ALL_STATUSES),
];
}
Please note that we use the same group name for both fields. It means that the combination of code
and status
fields will be unique among this group.
# Usage notes
Don't forget to add UniqueGroupProvider
to the Faker's provider collection so that it can be used:
$faker->addProvider(new UniqueGroupProvider($faker));
Also, you should clear unique groups after each test using UniqueGroupProvider::clearUniqueGroups
method, e.g in tearDown
method of your test case:
foreach (AbstractFactory::faker()->getProviders() as $provider) {
if ($provider instanceof UniqueGroupProvider) {
$provider->clearUniqueGroups();
break;
}
}