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

PaulClarke's avatar

Cannot correctly test a Queued Notification with email

Hi,

I am trying to properly test a Notification via email on a queue so that I can be absolutely clear that one user received it and another type of user did not.

The code works correctly, but I cannot get the test right. I am assuming that the reason is that I don't have a worker on the Queue during testing so the job is never processed and I am not certain how to change that. I have attempted to use the 'assertQueued' method, but no joy. Can anyone give me some suggestions please?

A User reports a Concern and another user is notified: In the Controller

    //Other stuff
    event(new ConcernReported($concern));

In the Listener

    public function handle(ConcernReported $event)
     {
            $dsl->notify(new NotifyDslOfConcern($event->concern, $dsl));
      }

The Notification class sends an email (standard MailMessage).

In my test I have attempted:

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

        $dsl = create(User::class);
        $dslFromOtherSchool = create(User::class);


        $this->actingAs($dsl)
            ->post('/safeguarding/concern/report', [
                'concern' => [
                    'incident_at' => Carbon::now(),
                    'reason' => 'A reason',
                    'details' => 'Some details'
                ]
            ])
            ->assertStatus(200);

    $concern = Concern::first();

    //Assert sent to DSL
         Mail::assertQueued(MailMessage::class, function ($mail) use ($dsl) {
            return $mail->dsl->id === $dsl->id;
        });

        Notification::assertSentTo(
            $dsl,
            NotifyDslOfConcern::class,
            function ($notification) use ($concern) {
                return $notification->concern->id === $concern->id;
            }
        );


    //Assert NOT sent to other user
    Mail::assertNotQueued(...);

    Notification::assertNotSentTo(
            [$dslFromOtherSchool],  NotifyDslOfConcern::class
        );
    }
0 likes
3 replies
bobbybouwmann's avatar

In your phpunit.xml your queue driver should be set to sync. This way it will always run it for you

<env name="QUEUE_DRIVER" value="sync"/>

Also I think you're testing this the wrong way around. In this test you should only look if the email is queue or not. It's not up to this test to see if the email was send or not. Instead you should separately test the ConcernReportedclass and in that assert that the notification is send.

1 like
PaulClarke's avatar

@bobbybouwmann Thank you. I can see I was mixing too many things together here. I did eventually solve it. The reason the Notification / Mail assertions were failing was not because of the queue, but an entirely different element of the application where a request was returning null, but the error was not bubbling up.

I have taken your advice and made a separate test so that each element is being tested separately. Thanks :)

Please or to participate in this conversation.