Testing Date And Time with Clock Objects

Did you ever write unit tests for code that dealt with date and time? Since time itself is out of your control, you might have used one of these approaches:

  • Test doubles, e.g. for the DateTime class in PHP. To make this work, DateTime or a factory thereof must be passed to the subject under test via dependency injection. My most popular blog post of all time is still “How to mock time() in PHPUnit” about mocking core functions like date() and time() if necessary (a hacky workaround, mind you)
  • Use derived values of the current time in fixtures and assertions, probably with some margin, e.g.
    assertEquals(\strtotime(“+1 day”), $cache->expiresAt(), “1”)
    where $cache->expiresAt() is the value we test and “1” is the allowed margin.

The latter is not very stable; it is likely that you run into edge cases where the tests are not deterministic. The former does not have this problem, but can result in a complicated setup of the test double.

Luckily, there is a third way, namely using a custom Clock (or Calendar) object that provides the current time and can easily be replaced with an (also custom) test double.

Continue reading on integer-net.com