Testing that event listeners are dispatched in Laravel

Last updated 5th September, 2023

When testing events and listeners in Laravel, it's crucial to validate that the event triggers the intended listener and that the listener performs the expected actions. However, it's equally important to ensure that the listener is correctly bound to the event. Let's have a look at how Laravel provides helpful methods to perform these validations.

Verifying Listener Registration with assertListening

Introduced in Laravel 8, the assertListening method allows you to check if a listener is registered to a specific event that you've defined. Here's an example of how to use it:

Queue::fake();

Queue::assertListening(
    expectedEvent: MyEvent::class,
    expectedListener: MyListener::class,
);

By using assertListening, you can confidently assert that the listener is properly bound to the event.

Testing Listener Execution with assertPushed

To verify that a listener is triggered when the associated event is fired, Laravel provides the assertPushed method:

Queue::fake();

Queue::assertPushed(
    CallQueuedListener::class,
    function ($listener) {
      return $listener->class === MyListener::class;
    }
);

Using the CallQueuedListener class and a callback, you can assert that the queued listener matches the expected class, ensuring the successful execution of the listener when the event is fired.

Asserting Absence of Queued Listeners with assertNotPushed

In cases where you need to confirm that a listener is not queued, Laravel offers the assertNotPushed method to invert the logic:

Queue::fake();

Queue::assertNotPushed(
    CallQueuedListener::class, 
    function ($listener) {
        return $listener->class == ListenerThatShouldNotQueue::class;
    }
);

By utilizing assertNotPushed, you can verify that a specific listener is not queued, ensuring that it does not trigger unintentionally.

Asserting Listener Invocation Count with assertPushedTimes

To verify that a listener is triggered a specific number of times when the associated event is fired, Laravel has a assertPushedTimes method. Allowing you to assert the exact count of listener invocations. Here's an example:

Queue::fake();

Queue::assertPushedTimes(
    job: MyListener::class,
    times: 3
);

By utilizing assertPushedTimes, you can ensure that the job is queued a specified number of times.

Testing Listeners on Specific Queue with assertPushedOn

Laravel's assertPushedOn method enables you to validate that a listener is dispatched to a specific queue when the associated event is fired. This is particularly useful when working with multiple queues in your application. Here's a working example:

Queue::fake();

Queue::assertPushedOn('special-queue', MyListener::class);

You can also specify a closure as the third argument to perform any additional assertions you might need:

Queue::fake();

Queue::assertPushedOn('special-queue', MyListener::class, function ($job) {
    // Perform extra assertions to pass test...
});

These testing methods are particularly valuable when validating the behaviour of event listeners, including scenarios where the shouldQueue method is utilized to control the listener's queuing logic. Here's an example of a usage of shouldQueue:

class Listener implements ShouldQueue
{
    public function shouldQueue(): bool
    {
        return $this->somethingToCheck === true; 
    }
}

By combining these testing snippets, you can thoroughly test the event-listener relationship and ensure that your application behaves as expected.

Conclusion

Laravel provides powerful tools to test events and listeners effectively, enabling you to validate the event-listener bindings and assert the desired listener execution with ease. Incorporate these methods into your testing workflow to ensure the reliability and correctness of your event-driven functionality.

No comments yet…

DevInTheWild.

Login To Add Comments.

Want More Like This?

Subscribe to occasional updates.