laracasts / TestDummy

Easy factories for PHP integration testing.
https://laracasts.com/lessons/whats-new-in-testdummy
MIT License
457 stars 80 forks source link

unique() in user Closures #94

Open h-collector opened 9 years ago

h-collector commented 9 years ago

Hey, @JeffreyWay this #90 issue isn't completely resolved, it still affects user Closures.

That is if you use consequent calls to static create, then it can still fail As an example, let's say we call it like this

Laracasts\TestDummy\Factory::times(10)->create(Website::class, ['user_id'=>$id]);
Laracasts\TestDummy\Factory::times(20)->create(Website::class);

Where Website factory is:

$factory(Website::class, function(Generator $faker)
{
    return [
        'title'     => $faker->sentence,
        'domain'    => $faker->unique()->domainName,
        'is_active' => $faker->boolean(90),
        'user_id'   => 'factory:' . User::class,
    ];
});

The chances are there will be uniques collision.

[Illuminate\Database\QueryException]                                                                                                                                                           
  SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: websites.domain

The problem is that Faker instance after latest commits (testing on 2.3.1) is Builders private property and we always get new Builder instances, so used values for attributes aren't shared.

    public static function create($name, array $attributes = [])
    {
        return (new static)->getBuilder()->create($name, $attributes);
    }
    public function getBuilder()
    {
        return new Builder($this->databaseProvider(), $this->factories());
    }

FakerAdapter (array notation) usage isn't completely affected because it share the same faker but not with simultaneous usage of user defined Closures so if we want to keep uniques then it should be reused, maybe as property in FactoriesLoader or Definition or as before in Factory?

This is still regression to version 2.1