Sooner or later you will get to the point that have to test time base conditions in your application.
Look at the following example:
Suppose you are developing an accounting system. Invoices are created in billing cycles which are allowed to run
at the beginning of every month.
How to test this method? Since new DateTime() is not accesible you have no chance to test the true/false
cases in an isolated, consistent way. You have a dependency to time and it is a moving window.
The easiest way would be to pass the current date to the method or to inject it from the test in the
Sligthly better, but both approaches have a downsides: if you create the date in the constructor, you bind the
now to the creation of your object which could be a source of hard to find bugs especially if you
have long living objects.
If you pass your current date to the method you don´t have that problem, but
you pollute your interface with quite specific information about what your method does.
An another approach could be to create a subclass from billing cycle, extract new DateTime() into a method and
override it a test specific subclass.
Now you can use the TestBillingCycle instead of BillingCycle in your unit tests and use a specific
date for each test case.
Seems to be straight forward, but as the system grows you will get many classes where you have to
handle issues. At some point it is important to travel with the whole system into a different time and
that is where subclassing has its shortcomings.
Java has no open classes, so simply mocking the genereal time mechanism like in timecop for ruby
is not possible. With powermock you can mock static methods and therefore System.currentTimeMillis() but
I don´t think that this a good solution since you can possibly break unrelated tests. And tests should be independent!
I prefer composition over inheritence, so an alternative approach could be:
With an object representing the time you got the full power of an OO design. Even if you are in the enterprise world, you can simply inject a
“ClockService” from your test context into your services, repositories, components, mapper or however.
And yes, you can use a plain old mockito mock instead of a FrozenClock.
Personally I like this solution since it models the dependency to time in an elegant way and it helps to test
time specific code.