nrofis
nrofis

Reputation: 9766

Laravel Model Factories ID not set

I have a regular User model. The system works fine when I use it. But now I am trying to create unit tests in the PHPUnit that integrated with Laravel.

I have a factory that creates a user:

$factory->define(App\User::class, function (Faker\Generator $faker) {
    return [
        'id' => $faker->randomNumber(9),
        'email' => $faker->safeEmail,
        'first_name' => $faker->firstNameMale,
        'last_name' => $faker->lastName,
        'password' => bcrypt(str_random(10)),
        'remember_token' => str_random(10),
    ];
});

I changed the User to have integer ID as the primary key but it not defined as auto-increment. So the factory create random number for the ID.

Also I have created the simple test:

public function test_id_is_visible() {
    $user = factory(App\User::class)->create();

    $this->actingAs($user);
    $this->visit('/userprofile');
    $this->see($user->id);
}

That test always fails, but it seems to be OK when I navigate to the page manually.

I have noticed that in the test the $user->id is always 0. Even it can't be 0 in the factory. I checked and Laravel insert the user correctly to the database and it have correct ID, but in the code I always get 0.

What can I do to get the correct value of the ID?

EDIT Now I see that if I changes $user = factory(App\User::class)->create(); to $user = factory(App\User::class)->make(); the user instance holds a correct ID. But why create clears the ID?

Upvotes: 9

Views: 10075

Answers (3)

Stelian
Stelian

Reputation: 848

You can write your tests like this:

$users = factory(User::class, 5)->make();
$users->each(function ($item, $key) {
    $item->id = ++$key;
});

Now each user will have an id, without the need to persist the models to database (using create() instead of make()).

public function test_id_is_visible() {
    $user = factory(App\User::class)->make();
    $user->id = 7;

    $this->actingAs($user);
    $this->visit('/userprofile');
    $this->see($user->id);
}

Upvotes: 2

Calvin Schemanski
Calvin Schemanski

Reputation: 399

Update for Laravel 5.8+ Make sure to set

public $incrementing = false;

on your model.

Upvotes: 13

nrofis
nrofis

Reputation: 9766

The problem happened because the ID is not defined as auto-increment.
More information you can found in:
https://stackoverflow.com/a/31350800/1725836

Even the question is for Laravel 4 it is still relevant for Laravel 5.2.

Upvotes: 3

Related Questions