Jobs

Queue it and forget it

Jobs move heavy work to the background. Test that they dispatch and run correctly.

Job
// app/Jobs/ProcessOrder.php
class ProcessOrder implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(public Order $order) {}

    public function handle(): void
    {
        $this->order->update(['status' => 'completed']);
    }
}
Controller
// app/Http/Controllers/OrderController.php
public function store(StoreOrderRequest $request)
{
    $order = Order::create($request->validated());

    ProcessOrder::dispatch($order);

    // ...
}
Feature Test — assert job is dispatched
// tests/Feature/Http/Controllers/OrderController/StoreTest.php
Queue::fake();

$this->post(route('orders.store'), $data);

Queue::assertPushed(ProcessOrder::class, function ($job) use ($order) {
    // return $job->order->is($order) && $job->order-> isInstanceOf(Order::class)
    $this->assertTrue($job->order->is($order));
    $this->assertTrue($job->order-> isInstanceOf(Order::class));

    return true;
});
Unit Test — assert job logic
// tests/Unit/Jobs/ProcessOrderTest.php
class ProcessOrderTest extends TestCase
{
    #[Test]
    public function order_status_is_updated_to_completed(): void
    {
        $order = Order::factory()->create(['status' => 'pending']);

        ProcessOrder::dispatch($order);

        $this->assertSame('completed', $order->fresh()->status);
    }
}