Framework: Calling truncate() prevents transaction rollback within unit tests

Created on 17 Jul 2019  路  2Comments  路  Source: laravel/framework

  • Laravel Version: 5.8.29
  • PHP Version: 7.3.7
  • Database Driver & Version: MySQL 8.0.16

Description:

If you call truncate(), either through the query builder, or via an Eloquent model, then the database records added during a test are not rolled back when using the RefreshDatabase.

Steps To Reproduce:

  • Create a test in which you insert a User model.
  • Call User::truncate() after creating the user.
  • Create a second test, which runs after the first, and test the total number of users with User::count(). It will equal 1 instead of 0.

Most helpful comment

Ah, I didn't know that! Thanks for the clarification.

It's not an issue as such since you can simply do something like this:

User::query() -> delete();

In any event, if someone searches for this again, they'll find this issue and the explanation.

All 2 comments

On MySQL, data definition language (DDL) statements like TRUNCATE cannot be rolled back and automatically commit the transaction: https://dev.mysql.com/doc/refman/8.0/en/cannot-roll-back.html

As a workaround, you can start a new transaction (this doesn't roll back queries before User::truncate()):

User::truncate();

DB::rollBack();
DB::beginTransaction();

User::create();

Ah, I didn't know that! Thanks for the clarification.

It's not an issue as such since you can simply do something like this:

User::query() -> delete();

In any event, if someone searches for this again, they'll find this issue and the explanation.

Was this page helpful?
0 / 5 - 0 ratings