Laravel

Write Test for Laravel Task Scheduler

For interactive laravel application, we need task schedular. Writing task schedular is very easy by the magic of laravel. However writing test for schedular is not that straight-forward. In this post, I will show you how can you easily test your schedular.

What you need?

  • A laravel application

#Table of Content

#Scenario

Imagine that in my app, I have a job called SendEmailReminderJob that run in every minute.

#Create Job

To create the job, you need to run the following command:

php artisan make:job SendEmailReminderJob

You will get a job like this:


namespace App\Jobs;

// Some imports... 

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

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        // Write your logic here 🙂
    }
}

#Schedule the Job

To schedule the job, you need to go to App\Console\Kernel.php file and add the following line in the schedule() method.

protected function schedule(Schedule $schedule)
{
    $schedule->job(new SendEmailReminderJob )->everyMinute();
}

ℹī¸ Check more how schedular works.

If your system configure queue properly, the SendEmailReminderJob job will run in every minutes.

#Write Test

I will create a test class for writing the test.

php artisan make:test SchedularTest

In the SchedularTest class,


<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Console\Scheduling\Event;
use Illuminate\Console\Scheduling\Schedule;
use App\Jobs\SendEmailReminderJob;
use Illuminate\Foundation\Testing\RefreshDatabase;

class SchedularTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function it_schedule_send_email_reminder_job_in_every_minute()
    {
        // Arrange + Act
        $jobClass = SendEmailReminderJob::class;

        // Fetches Laravel's scheduler instance 
        $schedule = app()->make(Schedule::class);

        // Only keep the events that match the $jobClass in their description field. 
        $event = collect($schedule->events())->filter(function (Event $event) use ($jobClass) {
            return $event->description === $jobClass;
        })->first();

        // Assert
        // Assertion ensures that the event passes all registered filters
        $this->assertTrue($event->filtersPass($this->app));

        // Confirm the expression which run in every second
        $this->assertEquals("* * * * *", $event->expression);
    }
}

#Run the test

Now run the test, and hope everything will pass for you.

php artisan test

Thanks for reading 🙂.