Testing with Joda Time
The alternative to dealing with java.util.Date which I wrote about in a previous post is to make use of the Joda Time library. I’m led to believe that a lot of the ideas from Joda Time will in fact be in Java 7.
Nevertheless when testing with Joda Time there are times when it would be useful for us to have control over the time our code is using.
Why would we want to control the time?
There are a couple of situations that come to mind where it may be useful to be able to control the time in a system:
-
There is a piece of code which only executes at a certain time of the day. To see if it executes correctly we need to be able to set the system time to be that time.
-
Date calculations - we want to do a calculation on a date and verify the result. We therefore need to be able to control the original date.
Given that, there are two approaches which I have seen to allow us to do this:
Freezing time
Joda includes a DateTimeUtils class which allows us to change the current time.
On the projects I’ve worked on we would typically wrap these calls in a more descriptive class. For example:
import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
public class JodaDateTime {
public static void freeze(DateTime frozenDateTime) {
DateTimeUtils.setCurrentMillisFixed(frozenDateTime.getMillis());
}
public static void unfreeze() {
DateTimeUtils.setCurrentMillisSystem();
}
}
This approach works better if DateTime is deeply engrained in the system and it is difficult for us to abstract dates behind another interface.
The benefit of taking this approach is that we can test for dates without having to change any of our code to add in another level of abstraction which leads to further complexity.
Time Provider
The alternative approach is to have a TimeProvider which we can pass around the system. This would typically be passed into the constructor of any classes which need to make use of time.
For example, we might have the following interface defined:
import org.joda.time.DateTime;
public interface TimeProvider {
public DateTime getCurrentDateTime() ;
}
We can then mock out getCurrentDate() to return whatever date we want in our tests.
The advantage of this approach is that it allows more flexibility around the implementation - it could be used to sync system and local machine dates for example - although at a cost of adding extra complexity.
This approach is similar to thehttp://martinfowler.com/eaaCatalog/plugin.html[plugin pattern] Martin Fowler details in Patterns of Enterprise Application Architecture in that we use one implementation of TimeProvider in our application and then a different version for testing.
I generally favour this approach if possible although if a quick win is needed then the first approach is fine.
About the author
I'm currently working on short form content at ClickHouse. I publish short 5 minute videos showing how to solve data problems on YouTube @LearnDataWithMark. I previously worked on graph analytics at Neo4j, where I also co-authored the O'Reilly Graph Algorithms Book with Amy Hodler.