I previously shared an issue I ran into with the RefreshDatabase trait and MySQL full-text indexes.
My solution was to use the DatabaseMigrations trait instead for those tests that needed full-text searching.
But what if your base feature test class includes the RefreshDatabase trait already?
This is the case in our projects, since I like to have all feature tests use it by default. Otherwise, it's too easy to forget it in one test class and end up with flaky tests.
In PHP, there's no way to "remove" a trait once it's imported in a base class, so what do we do?
In Laravel's test environment bootstrap, here's the relevant snippet of code where it uses these traits:
// in the InteractsWithTestCaseLifecycle trait, setupTraits method
$uses = array_flip(class_uses_recursive(static::class));
if (isset($uses[RefreshDatabase::class])) {
$this->refreshDatabase();
}
if (isset($uses[DatabaseMigrations::class])) {
$this->runDatabaseMigrations();
}
Notice that if more than one trait is present, both actions will be taken.
So even though we can't remove the trait, we can prevent it from doing any work in our one test class that we don't want to refresh.
We do this by overriding the refreshDatabase method, which would normally come from the RefreshDatabase trait.
In our overridden version, we have it do nothing, and it will continue on with the DatabaseMigrations action as we want without setting up a transaction.
// in our test class where we want to avoid RefreshDatabase behavior
public function refreshDatabase()
{
// We don't want to start a transaction for our full text tests
// This neutralizes the base class's RefreshDatabase trait behavior
}
If you use this approach, please include a comment to explain why you're overriding this method and then having it do no work.
And if you need this in more than one test class, you could also create a new trait called DatabaseMigrationWithNoRefresh that includes this method along with the framework's DatabaseMigrations trait, and then use that instead.
Here to help,
Joel
P.S. Would you like help leveling up the quality of your Laravel project? We have helped many companies do just that. Let's talk!