Laravel:如何为发送电子邮件的通知编写集成测试

时间:2019-03-14 06:51:17

标签: laravel testing notifications integration-testing

在触发通知或执行触发通知的操作后,如何测试电子邮件是否作为最终结果发送?

理想情况下,有一个通知仅用于发送电子邮件。我首先想到的是触发它,然后检查是否发送了Mail::assertSent()。但是,这似乎不起作用,因为Notification会返回Mailable,但不会调用Mail::send()

相关GitHub问题:https://github.com/laravel/framework/issues/27848

测试的第一种方法:


    /** @test */
    public function notification_should_send_email()
    {
        Mail::fake();
        Mail::assertNothingSent();

        // trigger notification
        Notification::route('mail', 'email@example.com')
            ->notify(new SendEmailNotification());

        Mail::assertSent(FakeMailable::class);
    }

Notification toMail()方法的外观如下:

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\FakeMailable
     */
    public function toMail($notifiable)
    {
        return (new FakeMailable())
            ->to($notifiable->routes['mail']);
    }

设置示例可用https://github.com/flexchar/laravel_mail_testing_issue

1 个答案:

答案 0 :(得分:1)

您可以使用mailCatcher然后扩展您的TestCase

class MailCatcherTestCase extends TestCase
{
protected $mailCatcher;

/**
 * MailCatcherTestCase constructor.
 * @param $mailCatcher
 */
public function __construct($name = null, array $data = [], $dataName = ''
) {

    parent::__construct($name, $data, $dataName);

    $this->mailCatcher = new Client(['base_uri' => "http://127.0.0.1:1080"]);
}

protected function removeAllEmails() {
    $this->mailCatcher->delete('/messages');
}

protected function getLastEmail() {
    $emails = $this->getAllEmail();
    $emails[count($emails) - 1];
    $emailId = $emails[count($emails) - 1]['id'];

    return $this->mailCatcher->get("/messages/{$emailId}.json");
}

 protected function assertEmailWasSentTo($recipient, $email) {
    $recipients = json_decode(((string)$email->getBody()),
        true)['recipients'];
    $this->assertContains("<{$recipient}>", $recipients);
}

}

然后您就可以在测试中使用

 /** @test */
public function notification_should_send_email()
{

    // trigger notification
    Notification::route('mail', 'email@example.com')
        ->notify(new SendEmailNotification());

    $email = $this->getLastEmail();
    $this->assertEmailWasSentTo($email, 'email@example.com');
}

因为您可以提取邮件,所以可以测试邮件正文,主题,抄送,附件等。

别忘了删除tearDown中的所有邮件

希望这会有所帮助。