Laravel 13.31 New Published on

Checking that an email is sent only once

assertSentOnce() and assertSentOnDemandOnce(): the Mail and Notification fakes finally say “exactly once” in one word.

Topics covered: TestingMailNotifications

New in Laravel 13.31. Mail::assertSent() passes as soon as an email has been sent, whether there was one or ten. To require a single send, you needed assertSentTimes(…, 1). The Mail and Notification fakes now have …Once assertions.

Before

Mail::assertSentTimes(CommandeConfirmee::class, 1);
Notification::assertSentOnDemandTimes(CommandeAFacturer::class, 1);

Since Laravel 13.31

Mail::assertSentOnce(CommandeConfirmee::class);
Notification::assertSentOnDemandOnce(CommandeAFacturer::class);

There is also assertQueuedOnce() for queued emails, and assertSentToOnce($notifiable, …) for a notification sent to a model.

Your task

POST /api/orders sends a confirmation to the customer (CommandeConfirmee) and notifies accounting (CommandeAFacturer). The test in tests/Feature/CommandeTest.php checks that both are sent, but not that they are sent only once: a duplicate send would go unnoticed. Strengthen it with the …Once assertions. Each mutant (a duplicated send) must make your tests fail.

Where the feature comes from: the original pull request.