Skip to content

Write Test for Laravel Task Scheduler

Posted on:September 2, 2023 at 02:00 PM

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?

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 🙂.