いつもお世話になっております。
Laravel8で作られたアプリケーションの、メール送信テストの書き方ついてお伺いいたします。
テスト対象は以下のメソッドです
public static function email($param) { try { Mail::to($email)->send(new BuildMessage($param)); } catch (\Swift_RfcComplianceException $e) { Log::debug('test', ['foo' => 'bar']); } }
メール送信成功時のテストは Mail::fake(); Mail::assertSent( ....を使って記述できたのですが、
エラーが起きた場合のテストは、
$this->expectException() や Mail::assertNotSent() ではうまくテストが通りませんでした。
結局他の方法でアサートするようにしたのですが、なぜテストがうまくいかなかったのか、理由を知りたいです。
エラーが起きたことは、
- メールが送信されなかった
- Swift_RfcComplianceExceptionが投げられた
のいずれかをアサートしようと考えました。
まず、1.のメールが送信されなかったことをアサートするテストを以下のようにしました。
public function email_RFCエラー($param, $expected) { $param = [ 'from' => 'admin@example.com', 'to' => 'test.@example.com', //rfcエラーになるメアド 'subject' => 'テスト', 'text' => 'テスト', ]; Mail::fake(); Message::email($param); Mail::assertNotSent(\App\Mail\BuildMessage::class); }
結果は、
The unexpected [App\Mail\BuildMessage] mailable was sent. ├ Failed asserting that actual size 1 matches expected size 0.
のようにエラーとなります。
メールは送信されたと書いてあるのですが、rfcエラーのメールアドレスを使用しているのになぜ送信されたことになるのでしょうか。
Mail::fake();を使わずにtinker等でrfcエラーのメアドを使いデバッグすると、正しくExceptionが投げられています。
次に、2.のSwift_RfcComplianceExceptionが投げられたことをアサートするテストを以下のようにしました。
public function email_RFCエラー() { $this->expectException(\Swift_RfcComplianceException::class); $param = [ 'from' => 'admin@example.com', 'to' => 'test.@example.com', //rfcエラーになるメアド 'subject' => 'テスト', 'text' => 'テスト', ]; Message::email($param); }
結果は、
Failed asserting that exception of type "Swift_RfcComplianceException" is thrown.
と、アサートは失敗となります。
テスト時にコードを1つ1つ追ってゆくと、ちゃんとcatchに入っているのですが、
テストのアサートは失敗するという状態です。
1、2 はなぜテストが失敗するのでしょうか。
何卒よろしくお願いいたします。
環境:
PHPUnit 9.5.18
Laravel 8
PHP 7.4
あなたの回答
tips
プレビュー