Quantcast
Channel: PHP8タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 521

【Laravel8・PHP8】PHPUnitのテストケースの中でseedingすると「PDOException There is no active transaction」とエラーが発生する。

$
0
0
背景 テストでマスターデータが必要になった。 テストケース中でシーディングするときに詰まったのでメモ。 環境 Laravel 8.40 PHP 8.0 MySQL 8.0 事象 テストケースの中でシーディング実行するとエラー発生 $ php artisan test ./tests/Unit/UserTest.php FAIL Tests\Unit\UserTest ⨯ seed --- • Tests\Unit\UserTest > seed PDOException There is no active transaction at vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:279 275▕ */ 276▕ protected function performRollBack($toLevel) 277▕ { 278▕ if ($toLevel == 0) { ➜ 279▕ $this->getPdo()->rollBack(); 280▕ } elseif ($this->queryGrammar->supportsSavepoints()) { 281▕ $this->getPdo()->exec( 282▕ $this->queryGrammar->compileSavepointRollBack('trans'.($toLevel + 1)) 283▕ ); Tests: 1 failed Time: 0.39s 実際のコード UsersTableSeeder <?php namespace Database\Seeders; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; class UsersTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('users')->truncate(); DB::table('users')->insert([ 'id' => 1, 'name' => 'test name 1', 'email' => 'test1@test.com', 'email_verified_at' => now(), 'password' => \Hash::make('password'), 'remember_token' => Str::random(10), ]); } } UserTest.php <?php namespace Tests\Unit; use Database\Seeders\UsersTableSeeder; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; class UserTest extends TestCase { use RefreshDatabase; public function test_seed() { $this->seed(UsersTableSeeder::class); $this->assertDatabaseHas('users', [ 'id' => 1, 'name' => 'test name 1', 'email' => 'test1@test.com', ]); } } 解決策 テストケース中で使っているTraitをRefreshDatabase から DatabaseMigrations に変える。 コード UserTest.php <?php namespace Tests\Unit; use Database\Seeders\UsersTableSeeder; use Illuminate\Foundation\Testing\DatabaseMigrations; use Tests\TestCase; class UserTest extends TestCase { use DatabaseMigrations; public function test_seed() { $this->seed(UsersTableSeeder::class); $this->assertDatabaseHas('users', [ 'id' => 1, 'name' => 'test name 1', 'email' => 'test1@test.com', ]); } } 結果 $ php artisan test ./tests/Unit/UserTest.php PASS Tests\Unit\UserTest ✓ seed Tests: 1 passed Time: 0.42s 調査 (WIP 検索してみるとLaravelやPHPのバージョン起因によるもの? 同様なエラーについて議論しているIssueを発見 コメントにはこの一文が Before PHP 8, while there's no active transaction PDO doesn't throw any error but this not the same in PHP 8. つまり8系以前でも同様の事象は発生していたが、エラーにならなかっただけと考えられる。 その事象がなぜ起きるかについては調査中 ※MySQLのドキュメントにはTruncateは暗黙的にコミットされるようなのでこれが関係している? ※Laravelのissueで修正については議論されている模様 補足 間違い等のご指摘歓迎いたします。

Viewing all articles
Browse latest Browse all 521

Trending Articles