Search code examples
phplaravel-5.3

Laravel Tests Database Doesn't Roll Back


I am trying to run CI tests with Laravel. The tests always fail, however, as the database doesn't appear to be rolled back after each test. This leads to errors such as the following:

Illuminate\Database\QueryException: SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'user_roles' already exists (SQL: create table `user_roles` (`id` int unsigned not null auto_increment primary key, `user_id` int unsigned not null, `role_id` int unsigned not null, `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate utf8mb4_unicode_ci)

I tried some code I found on the internet, which uses the DatabaseMigrations trait on the test class, which works fine for the first test, but doesn't work for the rest of them:

/**
* Set up the environment for testing.
*/
public function setUp()
{
    parent::setUp();
    $this->runDatabaseMigrations();

    // Create an example user
    $this->user = new User();
    $this->user->name = 'Test User';
    $this->user->email = '[email protected]';
    $this->user->password = '';
    $this->user->save();
}

And even tried adding a migrate:rollback call to the tearDown method of the tests, to no avail:

public function tearDown()
{
    parent::tearDown();
    $this->artisan('migrate:rollback');
}

Any ideas as to how to fix this?


Solution

  • So just after posting this question, I looked at the migrations, as I had realised there were a couple tables being migrated in before my user_roles table. This was when I noticed that the down function removed the foreign keys from the table, but didn't drop it:

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('user_roles', function (Blueprint $table) {
            $table->dropForeign('user_roles_user_id_foreign');
            $table->dropForeign('user_roles_role_id_foreign');
        });
    }
    

    Adding Schema::drop('user_roles'); to the down method, drops it after each test, and allows the rest of the tests after the initial one to function as intended.