Menu

Mocking the Clock

It's come to that time of the year when summer time kicks in, also known as daylight savings, when the clocks go forward. It's also coming up to the time of year, in the UK, that the new tax year starts. Now most of the time these items won't make a difference but if you write code which is datetime dependent or financial software which has tax year calculations in then it maybe time for some pain.

Over the years I have experienced a number of unit tests passing without issue on a Friday but Monday morning without any changes fail. Most of the time this is due to developers using DateTime.UtcNow (or variant) inside the code being tested but the tests expecting specific values.

So how do we solve this problem? We need to remove the direct reliance on DateTime and DateTimeOffSet static properties. Once we've done that we can unit test for different values and make our code more robust.

Lets look at the code.

All the examples are using the preview of aspnetcore 2.1 however none of the code is 2.1 specific so will work in current 2.x aspnetcore. The same principles can be applied to full framework using a DI container.

The Service Under Test (SUT)

For this example the sut will be a very basic MVC controller which outputs next hour:

And this will return next hour based on Utc. Now this in itself is clear however can potential cause issues with testing. So how do we resolve this to make sure that we use a well known starting point for testing purposes but at run time rely on the correct value? Abstract it away.

IClock interface

By using an interface to define the properties you want. I've seen it called IClock and IDateTimeOffSet so it's completely down to personal preference but the concept is the same.

Unit Testing

Now it's all working for the implementation at run time we need to make sure it is tested. This can be done in a couple of ways but the concept is the same; create a mock clock implementation and use it when constructing the SUT aka the HomeController.