I have a method which implements different logic on data fetched from a DB depending on what the current date is.
I want to test it by having the unit test create objects, save them in the DB and invoke the tested method. However, in order to have predictable results I need to change the system date each time and I don't know how to do that in Java.
Suggestions?
You can generate your expected results using the current date.
Or you write your system to use a date/time you give it when being tested (rather than the clock) That way the time is always what the test expects.
I use something like
In tests I use a FixedTimeSource which can be data driven e.g. set by inputs/events. In production I use a VanillaTimeSource.INSTANCE which ignores times in inputs/events and uses the current time.
You need to look at injecting something into your class that allows you to customize the way Time is presented.
For example
Now in your unit tests you can provide a fake implementation of time provider. In the real production code you can just return the current date time.
I had a similar problem recently with code I couldn't refactor too much (time constraints, didn't want to inadvertently break anything). It had a method I wanted to test which called System.currentTimeMillis() and the case I wanted to test would depend on what that value returned. Something like:
To allow unit-testing, I refactored the class so it had a helper method which was protected
and this method was called by doStuff(). This didn't change the functionality but now meant that when I call it in the unit-test, I could then override this to return a specific value, like
This does however mean that I've polluted the interface of my class, so you may decide the cost is too high. There are probably better ways if you can refactor the code more.