Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

laracoft's avatar

How to test sending of emails?

I never quite gotten used to requiring 2 classes (Mailable and User + record in user DB table) just to send an email

$user->notify(new \App\Notifications\Order\PaymentComplete($data));

So, what I normally do is write this instead

Mail::send('mail/autoreply', $sender,
    function ($mail) use ($sender) {
        $mail
            ->to($sender['email'], $sender['name'])
            ->subject('[Website Contact] '.$sender['subject']);
    });

My question is, is there a Laravel way to test Mail::send(...)?

0 likes
5 replies
martinbean's avatar

@laracoft A mailable literally encapsulates what you’re trying to do in your second example.

All a mailable class is, is a “blueprint” of an email you wish to send to users. And users are subjects that can be mailed. So create a mailable class instead of a random inline callback that can’t be re-used or tested anywhere:

Mail::to($user)->send(new AutoreplyMail($sender));

As @jaseofspades88 says, you can then use the mail fake to test the sending of these emails:

Mail::fake();

// Do something that sends an email...

Mail::assertSent(function (AutoreplyMail $mail) {
    $mail->assertHasTo('[email protected]', 'John Doe');
    $mail->assertHasSubject('[Website Contact] Test Subject');
    return true;
});
laracoft's avatar

Thanks, let me think about what is really at stake here.

I find it too much that I have to create the email, a mailable and a user in the database just to send 1 email.

Please or to participate in this conversation.