LoginSignup
9
6

More than 5 years have passed since last update.

MailTrackingを使って、Laravelでメール本文や件名のテストを行う

Posted at

はじめに

メールのテストをやっていて、
・メール本文のテストをしたい
・メール件名のテストをしたい
といった時、どうしていますか?

現在Laravelで用意されているテストでは、
assertSentassertQueuedくらいしか使えず、
メールが送信されたかどうかまでしかわかりません。

そこで、もっと詳しくメールのテストができる便利機能
MailTrackingについて書いてみようと思います!

MailTrackingとは

ざっくり言うと、メールのテストをより詳細に実行できるライブラリです。
メール本文の内容、メール件名、送信者アドレス、送信先アドレス、CC/BCCアドレスなど
様々なテストが可能です。
詳しくは↓
https://github.com/spinen/laravel-mail-assertions/blob/develop/readme.md

導入方法

超絶簡単!
$ composer require spinen/laravel-mail-assertions
これを打ち込むだけ。

また、テストファイルではこんなふうに書いてあげます。
(※その他、メールを送る処理の部分は別途記述が必要ですが、
今回はMailTrackingのみにフォーカスしています)


<?php
use Spinen\MailAssertions\MailTracking;

class MailTest extends TestCase
{
    use MailTracking;

    public function testMail()
    {
      //テストを書いていく
    }

使えるアサーション

  • seeEmailBcc
  • seeEmailCc
  • seeEmailContains
  • seeEmailContentTypeEquals
  • seeEmailCountEquals
  • seeEmailDoesNotContain
  • seeEmailEquals
  • seeEmailFrom
  • seeEmailPriorityEquals
  • seeEmailReplyTo
  • seeEmailSubjectContains
  • seeEmailSubjectDoesNotContain
  • seeEmailSubjectEquals
  • seeEmailTo
  • seeEmailWasNotSent
  • seeEmailWasSent

それでは見ていきましょう!(ΦωΦ)

送信先・送信元系

  • seeEmailTo
    • 送信先のメールアドレスを確認する
  • seeEmailCc
    • CCに指定されているメールアドレスを確認する
  • seeEmailBcc
    • BCCに指定されているメールアドレスを確認する
  • seeEmailFrom
    • 送信元に指定されているメールアドレスを確認する
  • seeEmailReplyTo
    • 返信先に指定されているメールアドレスを確認する

例えばこんな感じ。
・登録したら登録ユーザーにメールが飛ぶ。(TO:登録したメールアドレス)
・かつ、CCで自社にメールを送っている。(CC:nekocompany_info@example.com)
・送信元は自社である。(FROM:nekocompany@example.com)
こんな時のテストはこう書けばOK。

$this->post('/register', [
    'email' => 'user@example.com',
]);
$this->seeEmailTo('user@example.com');
$this->seeEmailCC('nekocompany_info@example.com');
$this->seeEmailFrom('nekocompany@example.com');

ちなみに、もし宛先が違っていた場合、
下記のようにエラーが出ます。

The last email sent was not sent to test@example.com.
Failed asserting that an array has the key 'test@example.com'.

(状況:
本当はuser@example.comに届いているが、
seeEmailTo('test@example.com')と書いてしまった。)

※ちょっと注意
実際どのメールアドレスに届いているのか、というのは
エラー文には出ないので、ログで確認する必要があります。

※ちょっと注意2
また、この記事で紹介するアサーションは基本的に、
2件以上メールを送っている場合、最後に送ったメールしか確認しない
ことに注意してください。

内容系

本文

  • seeEmailContains
    • メールの本文に指定文言が含まれていることを確認する(部分一致)
  • seeEmailDoesNotContain
    • メールの本文に指定文言が含まれていないことを確認する(部分一致)
  • seeEmailEquals
    • メールの本文が指定文言と完全に一致していることを確認する

件名

  • seeEmailSubjectContains
    • メールの件名に指定文言が含まれていることを確認する(部分一致)
  • seeEmailSubjectDoesNotContain
    • メールの件名に指定文言が含まれていないことを確認する(部分一致)
  • seeEmailSubjectEquals(seeEmailSubjectのみでもOK)
    • メールの件名が指定文言と完全に一致していることを確認する



例えばメールの内容が下記だった時・・・
~~~~~~~~~~~~~~~~~~~~~~~~~~
件名:
【猫カンパニーからのお知らせ】ご登録ありがとうございましたニャ〜
メール本文:
猫カンパニーへのご登録、ありがとうございました。
今後ともよろしくお願い致します。
ニャー!
~~~~~~~~~~~~~~~~~~~~~~~~~~

通るように書いたテストはこんな感じです。

//件名
$this->seeEmailSubjectContains('【猫カンパニーからのお知らせ】');
$this->seeEmailSubjectContains('ニャ〜');
$this->seeEmailSubjectEquals('【猫カンパニーからのお知らせ】ご登録ありがとうございましたニャ〜');
//本文
$this->seeEmailContains('猫カンパニーへのご登録')
$this->seeEmailContains('ニャー!')
$this->seeEmailEquals('猫カンパニーへのご登録、ありがとうございました。
今後ともよろしくお願い致します。
ニャー!');
//ちなみに、改行を含むseeEmailContainsも可能。
//その場合きちんと改行してあげないとエラーになります。
$this->seeEmailContains('致します。
ニャー!')

※ちょっと注意点
・エディタを使用している場合、インデントもチェックされるため、
改行後の自動インデントは削除する必要があります。

どういうことかと言うと、、、
こんなふうにテストを書いた時、エラーが出ます。

//エディタの関係でインデントがある時
        $this->seeEmailEquals('猫カンパニーへのご登録、ありがとうございました。
        今後ともよろしくお願い致します。
        ニャー!');
The last email sent did not match the given email.
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
 '猫カンパニーへのご登録、ありがとうございました。\n
-        今後ともよろしくお願い致します。\n
-        ニャー!'
+今後ともよろしくお願い致します。\n
+ニャー!'

このエラー文は、最初の一行目「猫カンパニーへのご登録、ありがとうございました。」までが一致しており、
それ以降は一致していないことを示しています。

また、Expectedが「テストで書いた値」
Actualが「実際に送られているメール」を指しています。

つまり、「テストではインデントがあると書いていたけど、実際のメールにはインデントがないよ〜」
と言っています。
ちょっと見た目が悪くなるかもしれませんが、、、お気をつけください。

送られたかどうか系

  • seeEmailWasNotSent
  • seeEmailWasSent

そのとおりメールが送られたかどうか、
または送られていないかどうか調べます。

※ちょっと注意
seeEmailWasSentの場合、「少なくとも1件のメールが送られているか」の確認をしているので、
何件送られているか確認したい場合は使わない方がベター。

送られた数系

  • seeEmailsSent
  • seeEmailCountEquals
    • これら2つとも、何件メールが送られているかを確認します。

もし2件メールを送っている場合はこんな感じ。

$this->seeEmailsSent(2);
$this->seeEmailCountEquals(2);

その他

  • seeEmailPriorityEquals
    • メールのプライオリティ(重要度)を判断する。1〜5の数字が入る。
  • seeEmailContentTypeEquals
    • メール形式を確認する。text/plaintext/htmlが入る。

このあたりは使用頻度少ないかもしれませんが、一応。

おわりに

メール内容や件名まで詳細にテストできるMailTracking、かなり便利でした!
調べていると「本文もテストできたらいいのに」といった声をちらほら見かけたので
記事にしてみました。

何かご指摘などございましたら、コメントをお願い致します!

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6