Wednesday, June 05, 2013

Running JUnit Tests in a Particular Time Zone

In the olden days, you might have done this with @BeforeClass and @AfterClass annotations. A neater way of ensuring that each unit test is run in the same time zone is to use the newer JUnit rules.
class TimeZoneTestRule implements TestRule {

  private final DateTimeZone zone;

  TimeZoneTestRule(DateTimeZone zone) {
    this.zone = zone;
  }

  @Override
  public Statement apply(final Statement base, Description description) {
    return new Statement() {

       @Override
       public void evaluate() throws Throwable {
         DateTimeZone defaultTimeZone = DateTimeZone.getDefault();
           try {
             DateTimeZone.setDefault(zone);
             base.evaluate();
           } finally {
             DateTimeZone.setDefault(defaultTimeZone);
           }
         }
      };
   }
} 
Now I want to ensure that my unit tests, which confirm that I'm parsing user input correctly, can compare the result to some constants. I annotate my test with:
  @Rule public TestRule timeZoneRule = new TimeZoneTestRule(DateTimeZone.forOffsetHours(2))