在触发通知或执行触发通知的操作后,如何测试电子邮件作为最终结果?
理想情况下,只有发送电子邮件的通知。我的第一个想法是触发它,然后检查是否发送了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 protected]')
->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
您可以使用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 protected]')
->notify(new SendEmailNotification());
$email = $this->getLastEmail();
$this->assertEmailWasSentTo($email, '[email protected]');
}
因为您可以获取邮件,以便您可以测试邮件正文,主题,抄送,附件等。
不要忘记删除tearDown中的所有邮件
希望这可以帮助。