johnnysoto
johnnysoto

Reputation: 1

Laravel PHPUnit not refreshing after every test

I am currently testing the login and register. The problem is that the database is not refreshing after every test so it's causing an error.

Error that I am getting: The user id should be 1, but because the database is not resetting after every test the user id is 2. I create a new user in my login and register test.

1) Tests\Unit\RegisterTest::successful
Failed asserting that a row in the table [users] matches the attributes {
    "id": 1,
    "username": "JohnRock",
    "email": "[email protected]"
}.

Found: [
    {
        "id": 2,
        "username": "JohnRock",
        "email": "[email protected]",
        "password": "$#^TTUG#$ORY#$&*RY#$YRY#$:RY:#$YRU$#YRP",
        "remember_token": null,
        "created_at": "2018-05-13 03:41:35",
        "updated_at": "2018-05-13 03:41:35"
    }
].
<?php

namespace Tests\Unit;

use App\User;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class RegisterTest extends TestCase
{

    use RefreshDatabase;

    /**
     * A basic test example.
     *
     * @return void
     */


    /** @test */
    public function successful_register()
    {
        $username  = 'JohnRock';
        $email     = '[email protected]';
        $password  = 'fjIRHJV@#(*UH(@#*H78))';

        $user = [
            'username'              => $username,
            'email'                 => $email,
            'password'              => $password,
            'password_confirmation' => $password
        ];

        $response = $this->post('/register', $user);

        $this->assertDatabaseHas('users', [
            'id'       => 1,
            'username' => $username,
            'email'    => $email
        ]);
    }

}
<?php

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class LoginTest extends TestCase
{

    use RefreshDatabase;

    /**
     * A basic test example.
     *
     * @return void
     */


    /** @test */
    public function login_successful()
    {
        $user = factory('App\User')->create();

        $response = $this->post('/login', [
            'username' => $user->username,
            'password' => $user->password
        ]);

        $response->assertRedirect('/');
    }

}

Upvotes: 0

Views: 5357

Answers (2)

Alessandro
Alessandro

Reputation: 575

You have to see phpunit.xml config file: if you are using conventional Test Database (not in memory database) it seems correct.

In Larav.6 the refreshTestDatabase() is called, defined in Illuminate\Foundation\Testing\RefreshDatabase trait.

    /**
     * Refresh a conventional test database.
     *
     * @return void
     */
    protected function refreshTestDatabase()
    {
        if (! RefreshDatabaseState::$migrated) {
            $this->artisan('migrate:fresh', [
                '--drop-views' => $this->shouldDropViews(),
                '--drop-types' => $this->shouldDropTypes(),
            ]);

            $this->app[Kernel::class]->setArtisan(null);

            RefreshDatabaseState::$migrated = true;
        }

        $this->beginDatabaseTransaction();
    }

Only on First iteration, when RefreshDatabaseState::$migrated is false, migrate:fresh is runned and RefreshDatabaseState::$migrated setted to true.

On the subsequent iterations (subsequent tests in the same class) this block is skipped.

Upvotes: 2

DevK
DevK

Reputation: 9942

Your LoginTest seems to be running before the RegistrationTest. And since you create a user there, it automatically gets id 1.

The RefreshDatabase doesn't remigrate for every test, it refreshes migrations before starting.

I recommend you remove the id from assertDatabaseHas, since don't really achieve anything by testing for id:

$this->assertDatabaseHas('users', [
    'username' => $username,
    'email'    => $email,
]);

Upvotes: 0

Related Questions