This tip was inspired by a recent discussion in the Mastering Laravel community around testing.
Let's say you have a copyright notice that shows the current year. In your Blade view, you might have something simple like now()->year()
.
This works fine, but how do you test it?
While it might be tempting, I would recommend not repeating that now()->year()
logic inside your test expectation. Why not?
I like to use the thought experiment of a "malicious pair" when thinking about the quality of a test. Is there anything a devious developer could do to break the code without breaking the test?
In this case, yes! They could go into the Blade file and replace now()->year()
with a literal value, like 2024
, and the test would still pass.
But on January 1, 2025, that test would fail and the copyright notice would also be incorrect.
How can we write a more resilient test? Take a look at this approach:
Carbon::setTestNow('2031-04-05');
$this->get('/')->assertSee('© 2031');
I'm using Carbon's testing helper to simulate the current date. Then my assertion can have a literal hard-coded value.
Short of monkey-patching how Carbon works, there is nothing a malicious dev could do to break this test without breaking the code. Sure, they could hard-code 2031 in Blade, but hopefully that wouldn't pass code review in the year 2024!
The thought process here isn't to really guard against a malicious dev on your team, but to think through the quality of a test.
And don't be afraid to hard-code expected values. Not only is it okay, it's actually better for your test, making it more resilient and easier to read.
Here to help,
Joel
P.S. Want to discuss coding topics like this with smart Laravel devs from all around the world? Join the Mastering Laravel community.