Laravelのテストでメール送信をモックにする方法

プログラミング
この記事は約3分で読めます。

概要

Laravelアプリケーションのテストを行うときに、メール送信部分をモック化する方法です。
テストの間はメールが実際に送られることがなくなり、加えて期待通りメールが処理されたかを Mail ファサードのアサーションメソッドで検証できます。

環境

  • PHP 7.3
  • Laravel 5.6

コード例

<?php

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Support\Facades\Mail;

class ApprovedTest extends TestCase
{
    /**
     * メールを送信したことを検証する
     */
    public function testSentApproved()
    {
        Mail::fake();

        // 何かを承認しメールを送る処理の呼び出し...


        // メールを1通送信したこと
        Mail::assertSent(Approved::class, 1);

        // 期待通りのメールであること
        Mail::assertSent(Approved::class, function ($mail) {
            return $mail->hasTo('...')
                && $mail->hasCc('....')
                && $mail->hasBcc('....');
        });
        
        // メールが送信されていないこと
        Mail::assertNotSent(Denied::class);
    }

    /**
     * メールがキューイングされたことを検証する
     */
    public function testQueuedApproved()
    {
        Mail::fake();

        // 何かを承認しメールを送る処理の呼び出し...


        Mail::assertQueued(Approved::class, 1);

        Mail::assertQueued(Approved::class, function ($mail) {
            return $mail->hasTo('...')
                && $mail->hasCc('....')
                && $mail->hasBcc('....');
        });

        Mail::assertNotQueued(Denied::class);
    }
}

補足

  • テストメソッド冒頭の Mail::fake() で、テスト中はメールが送信されなくなります
  • ここに登場する ApprovedDenied は、Laravelの Mailable を継承したクラスです
  • メール送信もしくはメールキューへの格納結果を、 assertSent assertQueued などのアサーションメソッドで検証できます

参考

公式ドキュメントにもそのままのサンプルがあります。こちらもあわせて見てみましょう。
* https://laravel.com/docs/5.6/mocking#mail-fake

URLのバージョン部分(上の場合/5.6/)を、見たいバージョンに変更しましょうね。

コメント

タイトルとURLをコピーしました