如何在 Laravel 中测试从通知发送的邮件

Ben*_*Ben 3 testing mocking laravel

我的用户可以指定是否立即向他们发送通知,或者每天收到任何待处理通知的通知。

以下内容适用于手动测试;现在我想围绕此编写一个功能测试,以确保发送电子邮件而不是短信或什么也没有。

public function test_instant_notification_is_sent(): void
{
    Mail::fake();

    $this->user = $user = factory(User::class)->create();

    $this->user->update(
        [
            'notification_frequency' => 'instant',
            'notification_method' => 'email',
            'notification_email' => $this->email,
        ]
    );

    $this->user->save();

    $email = ['subject' => 'subject', 'data' => 'data'];
    $sms = 'Test Notification';
    $database = ['some' => 'data'];

    $this->user->notify(new TestNotification($email, $sms, $database));

    Mail::assertSent(MailMessage::class);
}
Run Code Online (Sandbox Code Playgroud)

我已经写了一个TestNotification来配合它。

class TestNotification extends Notification
{
    use Queueable;

    public function __construct(array $email, string $sms, array $database)
    {
        $this->email = $email;
        $this->sms = $sms;
        $this->database = $database;
    }

    public function via($notifiable): array
    {
        return [$notifiable->preferredNotificationMethod()];
    }

    public function toDatabase($notifiable): array
    {
        return $this->database;
    }

    public function toNexmo($notifiable): array
    {
        return (new NexmoMessage)
            ->content($this->sms);
    }

    public function toMail($notifiable): MailMessage
    {
        return (new MailMessage)
            ->greeting($this->email['subject'])
            ->line('Testing Notifications!')
            ->line('Thank you for using our application!');
    }
}
Run Code Online (Sandbox Code Playgroud)

我的测试失败了,因为正如我现在所看到的,MailMessage不是 aMailable并且我认为Mail::fake()邮件断言仅适用于Mailable. 顺便说一句,如果我删除Mail::fake()电子邮件,则发送正常。

其他人如何在不实际发送电子邮件的情况下设法测试此功能?

Fat*_*XPC 7

测试通知时,您将需要使用Notification::fake()并做出这些断言。请参阅文档的“Notification Fake”以了解我的意思。

    public function test_instant_notification_is_sent(): void
    {
        Notification::fake();

        $this->user = $user = factory(User::class)->create();

        $this->user->update(
            [
                'notification_frequency' => 'instant',
                'notification_method' => 'email',
                'notification_email' => $this->email,
            ]
        );

        $this->user->save();

        $email = ['subject' => 'subject', 'data' => 'data'];
        $sms = 'Test Notification';
        $database = ['some' => 'data'];

        $this->user->notify(new TestNotification($email, $sms, $database));

        Notification::assertSentTo($this->user, TestNotification::class, function ($notification, $channels) {
            // check channels or properties of $notification here
            return in_array('mail', $channels);

            // or maybe check for nexmo:
            return in_array('nexmo', $channels);
        });
    }
Run Code Online (Sandbox Code Playgroud)