logo
podcast Podcast
get help Get Unstuck

Better assertions for things that happen more than once

Laravel has you covered

Joel Clermont
Joel Clermont
2024-09-05

Last month, I shared a testing tip on the benefits of making multiple separate assertions inside a closure instead of chaining them together.

Today I want to highlight one time you can't do this.

Let's say the code you're testing issues two events of the same type, but with different data.

Because it's being issued more than once, you can't use the closure approach I mentioned before to test both events.

Here's the approach I would use in this scenario:

Event::assertDispatchedTimes(OrderShipped::class, 2);
Event::assertDispatched(OrderShipped::class, function (OrderShipped $event) use ($user1) {
    $eventCustomer = getProperty($event, 'customer');    
    return $eventCustomer->is($user1);
});
Event::assertDispatched(OrderShipped::class, function (OrderShipped $event) use ($user2) {
    $eventCustomer = getProperty($event, 'customer');    
    return $eventCustomer->is($user2);
});

Because we're only using the return value to make our assertion, Laravel helpfully keeps track of both closures and makes sure they each pass at least once.

I still prefer the technique using specific independent assertions from the original tip, but when you're testing multiple instances of the same event (or mail, notification, job, etc), this is a great alternative.

Here to help,

Joel

P.S. If you appreciate these daily tips, you can support us by purchasing one of our Laravel books. You'll help us out and learn something in the process.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice you can use.