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
DateUtilsfactory class, which encapsulates the construction ofCalendarandDateinstances. Then you can swap this for a controllable factory. I.e., you have a second implementation ofDateUtilsthat also exposes asetCurrentTimemethod, and will then explicitly returnCalendarinstances set to that date.Or, you can use JMockit to actually "redefine" your call of
new GregorianCalendarso 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.
Yuval A : The first two suggestions, while are perfectly valid and even heavily used in other situations, feel a bit of an overkill to OP's needs. -
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.
NA : Actully I found JODA earlier today and realised that was what I actully wanted to be using. How would a testable JODA version look? Or should I simply assume that JODA is working correct as it should have it's own tests?duffymo : Check the JODA source out and see if it's unit tested. I'm betting that it is. Usually I assume a 3rd party library is tested until it gives me a reason to believe otherwise. At worst, they have a bigger user base than you do. Lots of people banging on code is a good way to find and fix lots of errors.
0 comments:
Post a Comment