Master testing events and jobs in Laravel using Event::fake() and Queue::fake(). Learn to verify background task dispatching without triggering side effects.
Previously in this course, we covered Asynchronous Processing with Queues in Laravel, where we learned how to offload heavy tasks to background workers. While dispatching jobs is straightforward, verifying they are actually fired—without executing the heavy work itself—is the hallmark of a resilient test suite.
In this lesson, we’ll move beyond testing simple database state and learn how to verify your application's "side effects" using fakes.
When you test a controller or service method that dispatches a job or fires an event, you don't want to actually send emails, process payments, or run expensive calculations. If you do, your tests become slow, fragile, and difficult to manage.
Laravel provides the Event::fake() and Queue::fake() facades to solve this. These tools intercept dispatch calls, preventing the actual code inside your listeners or job handles from running, while recording the fact that they were called.
When you call Event::fake(), Laravel stops all registered listeners from executing. Instead, it tracks the events dispatched during the request cycle.
Consider our project board, where we fire a TaskCreated event whenever a user adds a task.
PHPpublic function test_task_creation_fires_event() { Event::fake(); $this->postJson('/api/tasks', ['title' => 'New Task']); #6A9955">// Assert that the event was fired Event::assertDispatched(TaskCreated::class); }
You can also perform more specific assertions, such as checking if the event was fired for a specific task model:
PHPEvent::assertDispatched(TaskCreated::class, function ($event) use ($task) { return $event->task->id === $task->id; });
Testing background jobs is similar, but we often need to ensure the job was pushed to the correct queue or that it has the right parameters.
If you have a job that sends a welcome email or generates a report, you use Queue::fake() to intercept it:
PHPpublic function test_project_summary_is_queued() { Queue::fake(); $this->postJson('/api/projects/1/generate-summary'); #6A9955">// Assert the job was pushed to the queue Queue::assertPushed(GenerateProjectSummary::class); #6A9955">// Assert it was pushed to a specific queue Queue::assertPushedOn('reports', GenerateProjectSummary::class); }
In our project board project, let's ensure that when a user is assigned to a task, a NotifyUserOfAssignment job is pushed to the notifications queue.
TaskAssignmentTest.Queue::fake() at the start of the test.Queue::assertPushed to verify that NotifyUserOfAssignment is queued.assertPushed to verify the user_id matches the expected value.Event::fake() or Queue::fake(), your actual listeners will run. If those listeners interact with external APIs or databases, your test will fail or produce side effects.Event::assertDispatchedInOrder() or Queue::assertPushedInOrder().Queue::assertPushed but the job was never dispatched, the test will fail with a helpful message. However, if you are using Queue::fake() and the code path is never triggered, you might be testing the wrong thing entirely.Testing events and jobs is essential for building maintainable systems. By using Event::fake() and Queue::fake(), you effectively decouple your tests from the infrastructure concerns of your background workers. This allows you to verify that your application flow is correct—knowing that the right signals are sent—without the overhead of executing those signals.
Up next, we will look at Job Chaining and Batching, where we'll learn how to group related background tasks and handle them as a single atomic unit.
Learn how to rigorously secure your endpoints by testing Sanctum authentication. Master asserting unauthorized codes, token validation, and user mocking.
Read moreLaravel testing with Event::fake() helps you isolate logic by preventing side effects. Learn how to assert that events fired without triggering external code.
Testing Events and Jobs