Stephen S
Stephen S

Reputation: 81

Do MySQL database transactions break Laravel PHPUnit tests using RefreshDatabase or DatabaseTransactions?

I'm belatedly writing some PHPUnit feature tests for a project. One of these hits a number of routes which modify the database - and until now, I've been using database transactions in some of these routes.

If I use either the RefreshDatabase or DatabaseTransactions trait in my test, it fails with a strange error:

Illuminate\Database\Eloquent\ModelNotFoundException: No query results for model [App\Models\ClassM]

If I remove the traits (so the data will persist), the test passes.

I went through and removed all my database transactions from the relevant routes, and the test now does pass with RefreshDatabase.

My suspicion is that the problem is that MySQL doesn't support nested transactions, and both traits use transactions. But that would mean that if I want to run tests with RefreshDatabase (by far the best option!), I can't use transactions at all in my code.

Is that correct? It seems a major limitation.

Upvotes: 2

Views: 1648

Answers (1)

Stephen S
Stephen S

Reputation: 81

I've found a workaround - and it seems a little strange. I was mostly using the "manual" transaction methods - e.g.

DB::beginTransaction();
try {
    $user = User::create([...]); etc.
    DB::commit();
}
catch (...) {
    DB::rollBack();
}

I simply switched to the closure method:

DB::transaction(function () {
    $user = User::create([...]); etc.
});

No idea why that would have fixed it!

Upvotes: 3

Related Questions