Laravel PHP

Laravelでのキュー処理のテスト

Laravelを使っていてキュー処理(job)のユニットテストを行う場合についてです。
キューについて
公式: https://laravel.com/docs/5.5/queues
日本語: https://readouble.com/laravel/5.5/ja/queues.html

キューやジョブ自体については上記マニュアルや他にも調べればすぐにでてくるのでここでは割愛します。

テストの仕方

基本的にはキューを使って処理をする場合は
1. キューを積むまでのテストでちゃんとキューが積めているかを確認する
2. キューによるジョブの実行でその後の処理が正常に進むかを確認する
の2つのテストを作成するのがベストです。
なお、テスト時のキューの接続先が本番になっていないことは事前に確認しておいてください。

1. キューを積めているかのテスト

キューが積めているかの確認はキュードライバーによって変わりますが、単純にキューの有無を確認します。
参考に、データベースのjobsテーブルで管理している場合は下記のようになります。

$this->assertFalse(DB::table('jobs')->exists()); // キューがないことを事前確認
// テストしたい処理を実行
$this->assertTrue(DB::table('jobs')->exists()); // キューが積まれたか

2. キューの実行テスト

実行テストもそのままなのですがjobの実行クラスを直接たたきます。

$job = new ProcessImplementsShouldQueue($constructor_arg1, $constructor_arg2, ...);
$job->handle();

クラス名 ProcessImplementsShouldQueue の部分と引数はテストするクラスにあわせて適宜変えてください。
これでジョブが実行されるのでこの後にジョブ実行結果のassertをかけばOKです。

1つのテストでやる

次善の策として、どうしても一つのテストでキューの実行まで確認したいという場合はキューを積んだ後に

Artisan::call('queue:work', ['--once' => 'default']);

を実行するという手もあります。
artisan queue:workコマンドを呼び出しているんですが、それだけだと待機し続けてテストが進まないので--onceオプションをつけています。
これで作成したジョブが実行されるのでジョブのテスト結果のassertを続きに書けばテストできます。
ただし、これをするとテストの処理時間が伸びてしまうことや、キューを積む積まないなど色々なパターンのテストをし始めたときに複雑になるのでやはり基本はテストを分ける方がよいです。

-Laravel, PHP