[Laravel][PHPUnit] メール送信のテスト時に ErrorException: Undefined variable: message (View: */resources/views/emails/*.blade.php) が出る

2023/08/24

結論

たぶん、メールの文面用に用意した blade 内で、 $message->embed('public/images/logo.png’)  とか書かれてると思います。

メールのレンダリングを実行する前に、

$mail->viewData['message'] = new Message(new Swift_Message());

を実行してやることで、とりあえずしのげます。

詳細

メール送信のテストで、

  • メールが特定のテンプレートで送信されたか
  • メールの宛先がおかしくないか

といったテストコードを書くことはよくあると思います。

ただ、メール本文内の文字列を細かくチェックするようなときは、ちょっと面倒なコードになって、こんな感じになります。

        Mail::fake();
        // メール送信処理
        Mail::assertQueued(ReportMail::class, function ($mail) use ($user): bool {

            $mail->build();

            $mail->viewData['message'] = new Message(new Swift_Message());
            $body = view($mail->view, $mail->viewData)->render();
            if ($mail->hasTo($user->email)) {
                $this->assertFalse(str_contains($body, "2 件の申し込みがありました"), "メール内の数値が間違っています");
            }
            return true;
        });

 

この時に、

$mail->viewData['message'] = new Message(new Swift_Message());

がないと、

$body = view($mail->view, $mail->viewData)->render();

の部分で `ErrorException: Undefined variable: message (View: */resources/views/emails/*.blade.php)` のエラーが発生していたのでした。

通常の Mail ファサードでレンダリングした場合には $message を Laravel 側で勝手に解決してくれるのですが、Mail::assertQueued() に渡したコールバック関数内だとなぜだかうまくいかない模様…。

LaravelBlade,Mail,Mock,Test,UnitTest

Posted by S