概要
私の経験ではローカル開発以外にはsleep()
とusleep
機能はあまり使われていないですが、使った時には単体テストでsleepが行われたかどうかを確認するのはほぼ無理でした。Laravelの10.10のリリースでsleep機能のラッパーのSleepファサードが追加され、実装を初め、テストも簡単にできるようになりました!
使い方
眠らせる方法
Sleepファサードは生phpのsleep()
のエイリアスの関数があり、元の関数と同じように処理を一時停止したい秒数を引数として渡せます。
use Illuminate\Support\Sleep;
$isFinished = false;
while (!$isFinished) {
Sleep::sleep(2);
$isFinished = /* 処理が終わったかどうかのチェック */;
}
上記のラッパー機能だけではあまりメリットを感じる方がいないかと思いますが、
秒数だけではなく、ミリ秒
,マイクロ秒
,分
も設定できます。
さらにuntil()
の関数でタイムスタンプで決定の日付・~分後・~時間後まで処理を停止することも設定できます。
// 2秒に処理を一時停止
Sleep::for(2)->seconds();
// 200ミリ秒に処理一時停止
Sleep::for(200)->milliseconds();
// 2000マイクロ秒に処理一時停止
Sleep::for(2000)->microseconds();
// 決定した時間まで処理一時停止 (来年まで。。。。)
Sleep::until(now()->addYear());
and()
を使うことで、期間設定を組み合わせることもできます(たとえば秒数+マイクロ秒)。
// 2秒20マイクロ秒に処理停止
Sleep::for(2)->second2()->and(20)->microseconds();
眠ったかどうかのテスト方法
皆ご存知かと思いますが、ファサードの一つの強みがテスト内の使いやすさです。Sleepファサードももちろん、テストができるようのモックfake
の機能もあり、いくつかのアサーションもあります。
さらに下記の例のように生phpのsleep関数を使った場合、テストの処理でも一時停止され、テストが完了までに遅くなるかと思います。
use Illuminate\Support\Sleep;
$isFinished = false;
while (!$isFinished) {
sleep(2); // こうれがテスト内でも実行されますので、2秒停止される!!!
$isFinished = /* .... */;
}
そこで、fake()
の関数を使えば、テストの処理が停止せずに実行されるため、テストの実行時間が早くなります。
その上、Sleepファサードが実行された回数、停止した期間などのアサーションもあり、簡単に機能をテストができます。
use Illuminate\Support\Sleep;
// Sleepファサードをモック
Sleep::fake();
// Sleepファサードが2回実行されたかのチェック
Sleep::assertSleptTimes(2);
// Sleepファサードが一回も実行されなかったかのチェック
Sleep::assertNeverSlept();
// Sleepファサードが停止した時間が0秒かのチェック (実行された回数を問わず)
Sleep::assertInsomniac();
エンジニアのユーモア
この機能が便利といえば便利ですが、個人的にこのファサードについて一番面白かったのはPR内のやりとりでした。
元もこのファサードのクラス名前がメキシコの昼寝
と意味するSiesta(シエスタ)
で、他に「短い間」を表すSnooze
やRest
の提案もありました。ちょっとギャグっぽいですが自分はSnooze
が結構気に入りました。。。
どうしても、PRの作成者がSiesta
に気に入って、下記のようにインポートするタイミングで元の名前を使うつもりらしいです。
use Illuminate\Support\Sleep as Siesta;
その上、Sleep::assertInsomniac()
の関数の名前が不眠症
の言葉も使っていって、結構ユーモアのある名前になりました。Taylor Otwell さんがその関数のassertNeverSlept()
のエイリアスを作って、元の関数をイースター・エッグ(おまけ要素)として残しました。
思ったより、オープンソースソフトウェアの貢献者はギャグが好きですね。
まとめ
Laravel 10.10のリリースに処理を一時停止するSleep
ファサードがリリースされました。このファサードは生phpのsleep()
関数のラッパーで、テスト内で簡単にモックもアサーションもできます。便利でユーモアもある機能なので、ぜひ使ってみてください!