【PHPUnit】RefreshDatabaseについて
LaravelのPHPUnit で「おまじない」として毎回入れているuse RefreshDatabase
、
これはどのような動きをするか理解するため調べました。
RefleshDatabaseについて
テストケースの先頭にこんな感じで`use RefreshDatabase;'を記載している方は多いと思います。
この機能ですが、 テスト実行毎にデータベースを初期化するというものです。
例
RefreshDatabaseを使わない場合
カテゴリーというモデルがあったとして,それをテストメソッド内で5個のインスタンスを作る動きをします。
<?php class sample_Test extends TestCase { /** * サンプルテスト */ public function test_Sample(): void { Category::factory(5)->create()->each( function ($cat){ printf("ID: {$cat->id}\n"); } ); $this->assertTrue(true); } }
1回目の実行結果
ID: 1 ID: 2 ID: 3 ID: 4 ID: 5
2回目の実行結果
ID: 6 ID: 7 ID: 8 ID: 9 ID: 10
説明
2回目の実行結果は前回5個作っているので、6から再度作られます。 つまり、テスト実行毎に処理内容が変わってしまうわけです。
RefreshDatabaseを使う場合
use RefreshDatabase
をテストケースクラス先頭に追加しました。
<?php class sample_Test extends TestCase { use RefreshDatabase; //追加! /** * サンプルテスト */ public function test_Sample(): void { Category::factory(5)->create()->each( function ($cat){ printf("ID: {$cat->id}\n"); } ); $this->assertTrue(true); } }
1回目の実行結果
ID: 1 ID: 2 ID: 3 ID: 4 ID: 5
2回目の実行結果
ID: 1 ID: 2 ID: 3 ID: 4 ID: 5
説明
2回目の実行結果は前回5個作っているので、6から再度作られます。 つまり、テスト実行毎に処理内容が変わってしまうわけです。
まとめ
テストケースは毎回不変であるべき(じゃないとテストの意味がない)ので、
DBを使用するテストならuse RefreshDatabase
を使用して毎回DBを空にしてテストを行うことが最低条件になります。
こういう「毎回入れるもの」は入門本ではよくおまじないと言われますが、 実際に業務に使うなら、しっかりどういった動きをするものか把握してから使うべきと考えています。