A too-current-in-every-day-life example method :
public class SomeClass {
public String currentDateAsString() {
return new SimpleDateFormat().format(new Date(), "yyyyMMdd");
}
}The corresponding unit test will not work for so long :
@Test
public void testCurrentDateAsString() {
Assert.assertEquals("20100622", new SomeClass().currentDateAsString());
}
It will fail tomorrow ;-)
If you own the code, you should use a Date provider. Using library such as google collection (now guava), you can simply use a Supplier.
public class SomeClass {
public SomeClass(String pattern, Supplier dateSupplier) {
this.pattern = pattern;
this.dateSupplier = dateSupplier;
}
public String currentDateAsString() {
new SimpleDateFormat().format(this.dateSupplier.get(), this.pattern);
}
private final String pattern;
private final Supplier dateSupplier;
}Now the unit test will be much nicer and more it follows the Law of Demeter :
@Test
public void testCurrentDateAsString() {
Supplier dateSupplier = Suppliers.ofInstance(newDate(22,6,2010));
Assert.assertEquals("20100622", new SomeClass("yyyyMMdd", dateSupplier).currentDateAsString());
}*newDate may be a static date factory method you wrote, it is here for readability.
If the code come from scary legacy code, you should use jmockit or powermock (see Can I mock static methods).