Using the stricter assertSame check with collections

Without making the test more complex

Joel Clermont
Joel Clermont
2024-04-23

Lately, we've been trying out some of the stricter PHPUnit rules in our coding standards. One of them enforces use of assertSame over the looser assertEquals assertion.

After the small refactor Aaron suggested in a recent code review, I was now running into a test failure trying to use assertSame with a collection instead of an array.

This makes sense since collections are objects, and assertSame is looking for the exact same object instance, not just equal values. What to do?

One option is to ignore the rule and just use assertEqual, which will pass because it's only comparing values, not instance equality.

I took a different approach though. I just added toArray to the actual value in the test, allowing me to keep the stricter assertion:

$expected = [11, 23, 48];

// before
self::assertSame($expected, $model->methodBeingTested());

// after
self::assertSame($expected, $model->methodBeingTested()->toArray());

I know what you're thinking: "Joel, yesterday you got rid of a toArray call, and today you're adding one back in?" First of all, how dare you. Second of all, test code is different from app code, so I think this is a fair trade-off here.

It's a very small tweak to the test, but we keep the stricter assertion from our code standard in place.

Here to help,

Joel

P.S. Do you want to get better at writing tests? I'm working on a new course to share some of the best practices we've learned over the years. Hit reply and let me know if you'd like to be notified when it's ready.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼

Level up your Laravel skills!

Each 2-minute email has real-world advice you can use.