Blog

Fixing date in test using JUnit MethodRule

One of the principles of a good unit test is that they are repeatable. This is especially important if the tests involve dates. Typically this is programmed in the setUp and tearDown of the unit tests. This might lead to duplication if multiple tests depend on such a fixed date. Of course we can abstract this to an Abstract base class, but in the end we all know that reuse via inheritance is a bad idea. JUnit @Rule can be a solution for this.

The traditional approach would be (using joda-time library) something like this:

private final LocalDate LAST_WEEK = new LocalDate().minusWeeks(1);
@Before
public void setUp() throws Exception {
  DateTimeUtils.setCurrentMillisFixed(LAST_WEEK.toDateTimeAtStartOfDay().getMillis());
}

@After
public void tearDown() throws Exception {
  DateTimeUtils.setCurrentMillisSystem();
}

@Test
public void date_should_be_fixed() throws Exception {
  assertEquals(LAST_WEEK, new LocalDate());
}

With JUnit @Rule annotation we could create a rule for that:

public class FixedDateRule implements MethodRule {

  private final LocalDate fixedDate;

  public FixedDateRule(LocalDate fixedDate) {
    this.fixedDate = fixedDate;
  }

  @Override
  public Statement apply(final Statement base, FrameworkMethod method, Object target) {

    return new Statement() {

      @Override
      public void evaluate() throws Throwable {
        DateTimeUtils.setCurrentMillisFixed(fixedDate.toDateTimeAtStartOfDay().getMillis());
        try {
          base.evaluate();
        } finally {
          DateTimeUtils.setCurrentMillisSystem();
        }
      }
    };
  }
}

And use that Rule in a Test like this:

private final LocalDate LAST_WEEK = new LocalDate().minusWeeks(1);
@Rule
public FixedDateRule fixedDateRule = new FixedDateRule(LAST_WEEK);
@Test
public void date_should_be_fixed() throws Exception {
  assertEquals(LAST_WEEK, new LocalDate());
}

JUnit Rules provide a nice way to create a set of mixins that you can use in your JUnit tests without duplicating code or creating difficult inheritance trees.

Zilverline gebruikt cookies om content en advertenties te personaliseren en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services.

Okee