Test Laravel job delayed in Queue

 Reading time ~2 minutes

Heads up: this article is over a year old. Some information might be out of date, as I don't always update older articles.

Quick Tip

Since version 5.0, Laravel provides the possibility to delay the execution of a job later in time. You can accomplish this using the later method of the Queue facade:

<?php

$date = Carbon::now()->addMinutes(15);

Queue::later($date, new SendEmail($message));

Alternatively you may use the delay method when dispatching a job:

<?php

ProcessPodcast::dispatch($podcast)
    ->delay(Carbon::now()->addMinutes(15));

You can use a class that implements the DateTimeInterface interface or an instance of DateInterval class to specify the delay (Carbon helps a lot when dealing with dates). Alternatively, you may pass the number of seconds you wish to delay as an integer.

But how can we test if a job was delayed?

Laravel provides helpers for mocking events, jobs, and facades out of the box. We can use the Queue facade’s fake method to prevent jobs from being queued and also to make assertions on them.

For example, we can check if the job was delayed by checking the $delay property of the Illuminate\Bus\Queueable trait, which is used by all the queued jobs. This property can have one of these values \DateTimeInterface|\DateInterval|int|null.

<?php

namespace Tests\Feature;

use App\Jobs\ProcessPodcast;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function testJobDelayed()
    {
        Queue::fake();

        // [...] Run code that dispatches the job

        // Assert that Job was pushed with a delay
        Queue::assertPushed(ProcessPodcast::class, function ($job) {
            return ! is_null($job->delay);
        });
    }
}
comments powered by Disqus

Release Laravel jobs in queue without increasing attempts

Introduction

I’m currently working on a platform for processing videoclips. Our job is to extract as much information …