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

peterdickins's avatar

Unable to Assert Email Queued

I have a problem with a unit test not passing. The app loads users from a csv and sends a welcome email.

This is my test:

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

        Mail::assertNothingQueued();

        $this->loadUsers();

        Mail::assertQueued(Welcome::class);
    }

loadUsers() imports users into the database and dispatches a job for each user:

<?php

namespace App\Jobs;

...

class SendWelcomeEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private User $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        Mail::to($this->user->email)->send(new Welcome($this->user));       
    }
}

However when I run the tests I get the following:

1) Tests\Feature\LoadUsersTest::test_a_welcome_email_is_sent_when_a_user_is_loaded
The expected [App\Mail\Welcome] mailable was not queued.
Failed asserting that false is true.
0 likes
4 replies
Niush's avatar

Does Mail::assertSent(Welcome::class) work instead?

The Job is the one in Queue, not the Mailer. You should be testing that the Job was queued.

Queue::fake();
...
Queue::assertPushed(SendWelcomeEmail::class);

And, then may be the Mail sent assertion.

peterdickins's avatar

Thanks for your suggestion, I have a separate test for testing the job dispatching:

/** @test */
public function test_command_dispatches_welcome_email_jobs()
{
    Bus::fake();

    $this->loadUsers();

    Bus::assertDispatched(SendWelcomeEmail::class);
}

And this passes. I tried the assertSent function but that also fails

Niush's avatar

@peterdickins

So instead of Mail::assertQueued(Welcome::class) using Mail::assertSent(Welcome::class) should work, in my opinion. Because the Mail is sent directly not pushed to queue.

Niush's avatar
Niush
Best Answer
Level 50

@peterdickins You could alternatively test the Mail only, without calling loadUsers. As, you have already tested the Job anyway.

Doing something like this:

Mail::fake();
SendWelcomeEmail::dispatchSync($user);
Mail::assertSent(Welcome::class);
1 like

Please or to participate in this conversation.