I have some old convenience methods, written using Calendars, that I want to update to use the Java.time.* classes introduced in Java 8. Some of the methods in my class get
In your test (and only during test!) set the clock that your convenience class uses so that you can predict the desired/expected results independently of the computer clock:
public class ConvenienceTest {
@Test
public void testGetLocalHour() {
Convenience underTest = new Convenience();
ZoneId zone = ZoneId.of("America/Los_Angeles");
ZonedDateTime fixedZdt = ZonedDateTime.now(zone).withHour(0);
underTest.setClock(Clock.fixed(fixedZdt.toInstant(), zone));
assertEquals("24", underTest.getLocalHour24HourClock());
fixedZdt = fixedZdt.withHour(1);
underTest.setClock(Clock.fixed(fixedZdt.toInstant(), zone));
assertEquals("01", underTest.getLocalHour24HourClock());
fixedZdt = fixedZdt.withHour(23);
underTest.setClock(Clock.fixed(fixedZdt.toInstant(), zone));
assertEquals("23", underTest.getLocalHour24HourClock());
// TODO test with other time zones
}
}
For this to work it of course requires that your convenience class can accept a Clock and uses it:
public class Convenience {
private Clock clock = Clock.systemDefaultZone();
/** For testing only. Sets the clock from which to get the time. */
void setClock(Clock clockForTest) {
this.clock = clockForTest;
}
public String getLocalHour24HourClock() {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("kk");
ZonedDateTime zdt = ZonedDateTime.now(clock);
return zdt.format(fmt);
}
}
With this implementation the tests just passed on my computer.
Stepping a step back: if your convenience methods are but a thin layer on top of java.time, you may start to consider how much value a unit test has. If it is doing some real work (like formatting in the above example, something that regularly goes wrong), a test is valuable, but if a method just returns a value from a single call into java.time, you may not need a test. You shouldn’t test java.time, preferably only your own code.