junit4 idea and maven

Tue, Aug 19, 2008

I was adding some metadata unit tests to the Guanxi IdP and suddenly came across a very weird peculiarity. It’s perhaps a bit long winded but the following is similar to the test hierarchy I’ve been using. I start off with a base class that holds a lot of initialisation stuff:

public abstract class TestBase {
  protected static String testString = null;

@BeforeClass public static void init() { testString = “TEST”; } }

then extend that to head off into narrower test territory
public class SubTest extends TestBase {
  protected static String subTestString = testString + “_SUB_TEST”;
}
before reaching the main test:
public class TheTest extends SubTest {
  @Test
  public void test() {
    Assert.assertEquals(“TEST_SUB_TEST”, subTestString);
  }
}
The problem suddenly appeared where subTestString was ending up as “null_SUB_TEST” instead of “TEST_SUB_TEST”. This always worked and I seem to remember debugging it in IDEA. If it hadn’t, I’d have remembered and refactored. It certainly works in Maven2. Running the above test works just fine. Running it from IDEA, it fails.

What is happening is IDEA is instantiating in the order:

  • TestBase – static initialisation – testString = null
  • SubTest – static initialisation – testString is still null
  • TestBase::init – testString = “TEST”
  • TheTest::test = FAILS
whereas, what Maven is doing is:
  • TestBase – static initialisation – testString = null
  • TestBase::init – testString = “TEST”
  • SubTest – static initialisation – testString is “TEST”
  • TheTest::test = PASSES
Maven loads up each class in the hierarchy, starting at the base class (TestBase) and invokes the @BeforeClass before moving on to the next class in the hierarchy (SubTest).

The way round it is to add another @BeforeClass static method to SubTest:

public class SubTest extends TestBase {
  protected static String subTestString = null;

@BeforeClass public static void startup() { subTestString = testString + “_SUB_TEST”; } }

Note that I’ve named the @BeforeClass method in the subclass differently from the @BeforeClass method in the base class, otherwise the @BeforeClass init() will be overridden by @BeforeClass init in the subclass.

Having looked at this, I think I’ll toddle off and refactor the test structures.

comments powered by Disqus