이직 후 이전 개발자가 작성한 테스트코드에 RefreshDatabase 트레이트를 사용하는 코드로 리팩토리 중에 아래와 같은 에러를 마주치게 되었다.
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1305 SAVEPOINT trans2 does not exist
이 에러를 해결하는데 상당히 많은 고생을 하였다. 단위 테스트 수행 중에 롤백 관련된 문제였는데 어느 부분이 직접 원인인지 뚜렷한 에러 지점이 안 보여서 힘들었다.
에러의 원인은 트랙잭션내에서 롤백 할 수 없는 SQL 문구를(truncat()..) 작성하는 경우였다.
ref: https://dev.mysql.com/doc/refman/8.0/en/cannot-roll-back.html
public function testExceptionInTransactionWithTruncate(): void
{
// Given
$this->disableForeignKeys();
Team::truncate(); // https://dev.mysql.com/doc/refman/8.0/en/cannot-roll-back.html
$this->enableForeignKeys();
$this->expectException(\Exception::class);
// When && Then
DB::transaction(function () {
throw new \Exception();
});
}
migrate:fresh -> DB::beginTransaction() -> setUp() -> 단위 테스트 수행 -> tearDown() -> DB::rollback()
migrate:fresh 수행은 단위 테스트당 수행이 아닌 전체 딱 한번 만 수행 된다.