Back to Course |
Testing in Laravel 11: Advanced Level

Testing Jobs in Queue

In this lesson, I will show you how to test Laravel Job classes.


Job Example

Imagine you have ProductPublishJob and want to dispatch it from an Artisan command, Controller, or anywhere else.

The Job is straightforward: it finds the product by ID and publishes it by setting published_at.

app/Jobs/ProductPublishJob.php

use App\Models\Product;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
 
class ProductPublishJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 
public function __construct(public int $productId)
{}
 
public function handle(): void
{
$product = Product::find($this->productId);
 
if ($product && ! $product->published_at) {
$product->update(['published_at' => now()]);
}
}
}

The Job itself could be put into a queue, but you don't need to test it. You need to test that the Job changes the data successfully.


Test

So, in the test, we first check that the new product hasn't been published.

Then, you create a Job instance, manually call the handle() method, and check if the published_at isn't NULL anymore.

use App\Models\Product;
use App\Jobs\ProductPublishJob;
 
test('job product publish successful', function () {
$product = Product::factory()->create();
 
expect($product->published_at)
->toBeNull();
 
(new ProductPublishJob($product->id))->handle();
 
expect($product->refresh()->published_at)
->not->toBeNull();
});

We successfully tested that the published_at was NULL before the Job. After the Job, we refreshed the data from the database, and the published_at is not NULL.


This is how you can generally test the Job classes in Laravel by manually calling the handle() method.