A little note to avoid bugs in tests, or missing bugs: don’t use the current
date or time when writing unit tests.
When making up data for tests, it’s common to just use today’s date as it’s easy
to think up. This can catch you out when there is actually some hidden
dependency on the real time and your test starts failing the next day, month or
year. The test is currently passing by coincidence, which is hard to distinguish
from a real pass if you’re not careful.
It’s better to use a specific set of dates and times that cover some common
pitfalls such as daylight savings, leap years, year and month transitions and so
on. It’s also wise to make sure that both past and future dates are covered in
the tests.
On a related note, it’s always a good idea to pass the current time into a class
or method, rather than allowing it to grab it directly. It should be common to
see a parameter called now . It’s fine if this defaults to the current system
time, like this:
function fooMyBar(now: moment.Moment = moment.utc()) {
// whatever
}
This function is now far more testable, and you can easily set up useful test
cases without any awkwardness or special libraries:
// Given it is February 29th;
const now = moment.utc('2020-02-29');
// When we foo the bar;
fooMyBar(now);
// Then something in particular should happen;
// ...
Coming back to avoiding the current date in test data, the principle applies to
test data more generally – avoid test data that coincidentally happens to be
true. Well, test those cases, but make sure to also test the cases which
distinctly differ from any expected reality.
This is another reason to try and keep the habit of getting a failing test case
first, to make sure your test isn’t passing by coincidence.
View post:
Choosing dates and times in tests
|