About refreshDatabase trait in laravel unit testing

85 views Asked by At

I've my migrations at two different default location (database/migrations/tables/) and (database/migrations/foreign/) and i want to use the RefreshDatabase trait, however it uses the default migration location.

How can i specify or override at setUp or somewhere the "path" option for this migrations?

The only way that i found to do that is overriding "refreshInMemoryDatabase" and "refreshTestDatabase" methods but im thinking in a better way. Can anyone help me in this trick!

2

There are 2 answers

0
Denis Sinyukov On

Override the refreshTestDatabase method of RefreshDatabase trait by specifying --path=/app/database/migrations/tests. It will be the best way

protected function refreshTestDatabase()
{
    if (! RefreshDatabaseState::$migrated) {
        $this->artisan(
            'migrate:fresh --path=/app/database/migrations/tests',
            $this->migrateFreshUsing()
        );

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

        RefreshDatabaseState::$migrated = true;
    }

    $this->beginDatabaseTransaction();
}
0
patricus On

The trait has two methods that are used to provide options to the migrate command:

  • migrateUsing() when using a sqlite in-memory database
  • migrateFreshUsing() when not using a sqlite in-memory database

As an example, if using a sqlite in-memory database, you could do this:

/**
 * The parameters that should be used when running "migrate".
 *
 * @return array
 */
protected function migrateUsing()
{
    return [
        '--seed' => $this->shouldSeed(),
        '--seeder' => $this->seeder(),
        '--path' => 'database/migrations/tables',
        '--path' => 'database/migrations/foreign',
    ];
}

Or, if you want to be able to call the original function, you can rename it when using the trait:

use RefreshDatabase {
    migrateUsing as traitMigrateUsing;
}

protected function migrateUsing()
{
    // Merge in your new values with the default values.
    return array_merge($this->traitMigrateUsing(), [
        '--path' => 'database/migrations/tables',
        '--path' => 'database/migrations/foreign',
    ]);
}

If you're not using an in-memory database, you would need to override the migrateFreshUsing() method instead. In this case, the default logic is slightly more complicated, so it would probably be better to call it from the trait. That would look like:

use RefreshDatabase {
    migrateFreshUsing as traitMigrateFreshUsing;
}

protected function migrateFreshUsing()
{
    // Merge in your new values with the default values.
    return array_merge($this->traitMigrateFreshUsing(), [
        '--path' => 'database/migrations/tables',
        '--path' => 'database/migrations/foreign',
    ]);
}