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);
}
}