Is there any way to manipulate the current time in a jUnit 4.5 test? I have the following method which I'd like to have a unit test for
public String getLastWeek() {
GregorianCalendar c = new GregorianCalendar(TimeZone.getTimeZone("Europe/Stockholm"));
c.setFirstDayOfWeek(GregorianCalendar.MONDAY);
c.add(GregorianCalendar.WEEK_OF_YEAR, -1);
return c.get(GregorianCalendar.YEAR) + " " + c.get(GregorianCalendar.WEEK_OF_YEAR);
}
One way to make it easier to test is to split it into two methods
public String getLastWeek() {
GregorianCalendar c = new GregorianCalendar(TimeZone.getTimeZone("Europe/Stockholm"));
return getLastWeekFor(c);
}
public String getLastWeekFor(GregorianCalander c) {
c.setFirstDayOfWeek(GregorianCalendar.MONDAY);
c.add(GregorianCalendar.WEEK_OF_YEAR, -1);
return c.get(GregorianCalendar.YEAR) + " " + c.get(GregorianCalendar.WEEK_OF_YEAR);
}
That lets me test the week subtraction logic, but leaves getLastWeek untested and I prefer to have just one method for this.
You have no real way of manipulating system time.
Actually, you refactored the method rather nicely in order to make it testable. I would keep it at that.
I can see two paths here.
Either, create a DateUtils
factory class, which encapsulates the construction of Calendar
and Date
instances. Then you can swap this for a controllable factory. I.e., you have a second implementation of DateUtils
that also exposes a setCurrentTime
method, and will then explicitly return Calendar
instances set to that date.
Or, you can use JMockit to actually "redefine" your call of new GregorianCalendar
so instead a mock instance is returned. I have not done this myself, but there is a description here.
Your option, breaking the method into two methods, is also a perfectly valid option. I think that it is what most people do - including myself: but the truth is that it does hurt your design, especially if the class is exposed to other code.
Looks like you're trying to recreate what JODA Time does. I'll cite it in case you aren't aware. You can make the trade-off between reinventing the wheel and adding a dependency.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With