Mock the Clock

Say you have a test case “Given a departure more than 90 days from now, when a passenger logs on, should present a premature login page”.

You first thought is of course to set up a mock for departures so that when we simulate the log on, system logic will discover that there are more than 90 days. So you take the current time and adds 90 days to set the time for the mocked departure. Easy. But it fails twice a year when we go to and from daylight saving. You could fix that too, of course. But then we discover a  bug when it is exactly 90 days from now and you need to write a test that shows that. Again, you pick the current time and start calculating.

Later on, you discover that some of the manual tests are taking very long time. It turns out that the testers are constantly changing their test data to match the current date. Lets say that we have a test that involves the birthday of somebody. So the testers have to manipulate the test data to change birthdays for people in their test data.

That has to be waste.

“Now” is a concept that is readily available to your code so it will no specific point in the code where you can change the notion of “now” for the system. Also, how fast shall time pass? If there are test cases that requires time to pass, it might be useful if you could throttle the speed of the clock.

My advice is to consider which of your tests that are affected by current date and time passing. Create a utility that will return the current time as is or some fake time depending on configuration.

E.g. a system property in Java could be a date-time string which is read if the system is not in production mode. A more advanced variant would include a user interface for easy access to the meaning of “now”.

There are of course other solutions, but I am surprised that the problems with time are overlooked so often.

3 responses on “Mock the Clock

  1. A simple, test-friendly design pattern for us fortunate Spring users:

    public interface SystemClock {
      Date getDate();
    }
    
    @Component
    public class SystemClockImpl {
      public Date getDate() {
        return new Date();
      }
    }
    
    @Service
    public class SomeServiceImpl {
    
      @Autowired
      private SystemClock systemClock;
    
      public void someServiceThatNeedsCurrentTime() {
        Date now = systemClock.getDate();
        ...
      }
    }
     
    

    In unit tests, it is simple to mock the SystemClock, making it return whatever your tests require.

  2. Agre, the problem of time (and date) is a reoccuring pattern. For example, in banking systems often two dates exists, “now” and “bankday” where bankday referrs to the bookeeping date.

  3. The clock is a physical resourse like DB, GUI and IPC and need to be mocked when running unit tests.

    When testing real-time (embedded) SW it is absolute necessary to “mock the clock”. For example: If you have a critical limit of 100 milliseconds you want to verify proper behavior for 99, 100 and 101 milliseconds. It is impossible to use the real clock when running these test cases.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.