mcbates's avatar

How to test if scheduler only runs at given times?

I have a weekly summary email that I trigger via the scheduler in app/Console/Kernel.php:

protected function schedule(Schedule $schedule)
    {
        $schedule->call(new NotificationController)->weeklyOn(6, '8:00');
    }

It does work in real life, but I have problems testing it, because it supposedly sent the mail on other days as well.

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

    Carbon::setTestNow('first saturday of December 2019 8am');
    $this->artisan('schedule:run')->assertExitCode(0);
    Mail::assertSent(UpcomingBirthdays::class);

    Carbon::setTestNow('second monday of December 2019 8am');
    $this->artisan('schedule:run')->assertExitCode(0);
    Mail::assertNotSent(UpcomingBirthdays::class);
}

The second block should assert that it did not send, but it says it sent. What am I doing wrong here in the test?

0 likes
2 replies
BryanK's avatar

I dont know if its a typo just here or in your code itself, but it should be

Mail::assertNotSent

but you have

assertDontSent

You might want to pass a closure on this for who the mail is being sent or not sent to for verification and split the tests for it does and it doesnt.

$emailingTo = ‘[email protected]’;
Mail::assertNotSent(UpcomingBirthdays::class, function ($mail) use ($emailingTo) {
            return $mail->hasTo($emailingTo->email);
        });
mcbates's avatar

Yes, @bryank, that was just a typo with ::assertDontSend, I corrected it. I also tried your closure, but still get the error:

The unexpected [App\Mail\UpcomingBirthdays] mailable was sent.
   ├ Failed asserting that false is true.

Please or to participate in this conversation.