I'm using JodaTime 2.1 and I'm looking for a pattern to unit test code which performs date/time operations to make sure it behaves well for all time zones and independent of DST.
Specifically:
- How can I mock the system clock (so I don't have to mock all the places where I call
new DateTime()
to get the current time) - How can I do the same for the default time zone?
Change for single test
You can use a
@Rule
for this. Here is the code for the rule:You can use the rule like this:
This will change the current time zone to UTC before each test in
SomeTest
will be executed and it will restore the default time zone after each test.If you want to check several time zones, use a rule like this one:
Put all the affected tests in an abstract base class
AbstractTZTest
and extend it:That will execute all tests in
AbstractTZTest
with UTC. For each time zone that you want to test, you'll need another class:Since test cases are inherited, that's all - you just need to define the rule.
In a similar way, you can shift the system clock. Use a rule that calls
DateTimeUtils.setCurrentMillisProvider(...)
to simulate that the test runs at a certain time andDateTimeUtils.setCurrentMillisSystem()
to restore the defaults.Note: Your provider will need a way to make the clock tick or all new
DateTime
instances will have the same value. I often advance the value by a millisecond each timegetMillis()
is called.Note 2: That only works with joda-time. It doesn't affect
new java.util.Date()
.Note 3: You can't run these tests in parallel anymore. They must run in sequence or one of them will most likely restore the default timezone while another test is running.