Testing that a controller queued a job by starting a worker and waiting is slow and flaky, and testing it by asserting on the queue table couples the test to the driver.
public function testPlacingAnOrderQueuesTheReceipt(): void
{
Queue::fake();
$this->post('/orders', $this->validPayload())->assertCreated();
Queue::assertPushed(SendReceipt::class, function ($job) {
return $job->orderId === Order::latest()->first()->id;
});
}
// and the job's own test, separately, with no HTTP involved
public function testTheReceiptJobSendsOne(): void { /* ... */ }
Splitting it in two is the pattern: one test says the right job was dispatched with the right arguments, the other says the job does the right thing. Together they cover the behaviour without ever running a worker. The closure checking the payload is the part people omit, and without it the test passes when the job is dispatched with the wrong id — which is the bug most likely to occur.