こんにちは、システム開発事業部の千代田です。
今回は、PHPUnitにてflashメッセージをアサーションメソッドで検証する必要がありましたので、その方法について備忘録を残しておきたいと思います。
はじめに
LaravelのControllerにて下記のようなプログラムがあった場合、どのようにこのメッセージが返っていることを検証しますか?
1return flash('保存できませんでした。')->error();
メッセージがレスポンスに含まれているのであればassertJsonなどでレスポンスの中身を検証できますが、これはレスポンスに含まれていないため、少し複雑になってしまいます。
こちらを、失敗した実装と成功した実装に分けて説明します。
検証に失敗する実装
検証コードとして最初に実装したものが以下のコードになります。
1$response->assertSessionHas('flash_notification', function ($messages) {
2 return collect($messages)->contains(function ($message) {
3 return $message['message'] === "保存できませんでした。"
4 && $message['level'] === 'error';
5 });
6});
こちらは実装前の調査にて、フラッシュメッセージはセッションにflash_notification というキーの値として保存されることが分かりましたので、セッションデータの検証ができるassertSessionHas で中身を比較しています。
また、flash() の第一引数は各配列のmessage として、メッセージレベル(errorやsuccessなど)はlevel として保存されているため、これらを出力されてほしい内容と比較しています。
しかし、このコードを検証に使用した状態でテストを実行すると、エラーが発生しテストを正常に終了することができませんでした。
検証に成功した実装
続いて、失敗後に修正したプログラムが以下になります。
1use Illuminate\Support\Collection;
2use Laracasts\Flash\Message;
3
4$response->assertSessionHas('flash_notification', function (Collection $messages) {
5 return $messages->contains(function (Message $message) {
6 return $message->message == "保存できませんでした。"
7 && $message->level == "danger";
8 });
9});
変更点
- flash_notification は下記のような構造を持っているため、1つ目のコールバック関数での$messagesの型をCollectionとして指定します。
1'flash_notification' => 2 \Illuminate\Support\Collection::__set_state(array( 3 'items' => 4 array ( 5 0 => 6 \Laracasts\Flash\Message::__set_state(array( 7 'title' => NULL, 8 'message' => <flash()の第一引数として指定したメッセージ>, 9 'level' => <メッセージレベル>, 10 'important' => false, 11 'overlay' => false, 12 )), 13 ), 14 'escapeWhenCastingToString' => false, 15 )),
- これにより、collect($messages)を使用しなくてもコレクションとして扱うことができます。
- contains()のコールバック関数での第一引数では、$messageの型をLaracasts\Flash\Message として指定します。
- flash() を使用してフラッシュメッセージを設定すると、Laracasts\Flash\Message 型のオブジェクトとして保存されるためです。
- Message $message と指定したことで、$message の各プロパティにはアロー演算子でアクセスできるようになります。これらを想定しているエラーメッセージと比較し、両方が一致していればtrueを返すようにします。
こちらの方法でテストを実行したところ、想定したエラーメッセージが返ってきていることを検証することができました。
おわりに
いかがでしたでしょうか。
フラッシュメッセージはセッションに保存されていることもあり、検証が一筋縄では行きませんでしたが、構造がわかってしまえば比較的容易に実装できると思います。
この記事が少しでも参考になれば幸いです。