結論
DBの値を操作するテストを実行する場合、
既存のDBのレコードはそのままに変更した値だけ元に戻したい
そんな時はDatabaseTransactionsを使おう🍄
事例
- 有用な大量の既存テストデータが存在するDBを使って、レコード追加のテストを行う
- 普通にテストを実行すると、都度レコードが増えてしまう……🥺
- RefreshDatabaseを使ったら、既存のテストデータまで消えた🥺🥺🔪🔪🔪
DatabaseTransactions とは
- テスト実行中のみ有効なトランザクションを設定する
- 自動的にsetUp()でbeginTransactionして、tearDown()時にrollbackする
解決方法
以下のように、DatabaseTransactionsを使う
class HogeTest extends TestCase
{
use DatabaseTransactions;
/**
* @var HogeService
*/
private $hogeService;
/**
* 初期データ投入.
*/
public function setUp(): void
{
parent::setUp();
$this->hogeService = app()->make(HogeService::class);
}
/**
* @test
*/
public function insertRecord_正常()
{
$name = 'fuga';
$no = $this->hogeService->insertRecord($name);
$this->assertSame(1, $no);
}
}
補足
- 自動採番する項目は、レコードに登録されていなくても、
内部的にはカウントされている点に注意
例)
既に4回、DatabaseTransactionsを使ったテストを実行していた場合、
その後DatabaseTransactionsを使わずに新規追加された
以下のレコードのno(bigIncrements)は1ではなく5になっている
mysql> select no, user_id, created_at from reports;
+----+------+---------------------+
| no | name | created_at |
+----+------+---------------------+
| 5 | fuga | 2020-09-24 19:14:47 |
+----+------+---------------------+
1 row in set (0.01 sec)