I have an interesting JUnit problem here (JUnit 4.12). I have a base class that only has static methods. They have to be static, because of the way they're used. I inherit other classes from the base class. So, if the base class is Base
, we have ChildA
and ChildB
.
Most of the methods are contained in the base class, but it has to know which child it actually is (just calling the methods as the base class is invalid). This is done via a static data member in the base class:
public class Base {
protected static ChildType myType = ChildType.Invalid;
...
}
Each child sets the data member via a static initializer, thus:
static {
myType = ChildType.ChildA;
}
Then when the methods are called, the base class knows what type it is and loads the appropriate configurations (the type is actually a configuration name).
This all works perfectly when running the application. Stepping through it in the debugger and through log messages, I can see the appropriate types are set and the methods load the appropriate configurations based on the child type.
The problem arises when using JUnit. We have some JUnit tests to test each of the base class methods. Since calling the methods on just the base class is invalid, we call the methods on the child classes, thus:
bool result = ChildA.methodTwo();
This ''always fails''. Why? The static initializer never gets called. When running the code as an application, it gets called, and everyone is happy. When I run it as a JUnit test, the static initializer is skipped and the methods have invalid data. What is JUnit doing that skips the static initializer? Is there a way around it?
Details
In reality, we're not calling the method as I posted above. I just wanted the example to be as clear as possible. In reality, we have a Web Service written with the Jersey framework. The method called is one of the REST endpoints.
@POST
@Produces(MediaType.TEXT_PLAIN)
public String methodPost() {
...
return new String( itWorked ? "success" : "fail" );
}
And we call it like this (sorry about the ugly syntax, it's just the way it works):
@Test
public void testThePost() throws Exception {
javax.ws.rs.core.Response response = target("restapi/").request().post(Entity.entity(null, MediaType.TEXT_PLAIN));
assertEquals( 200, response.getStatus() );
}
All the GET tests work, and the static initializer is called on all of them. It's just this POST that fails, and only when running the JUnit test.
ChildA.methodOne()
. At that point--at least when running the code normally--it calls the static iniitalizer and sets the static data member. The data member identifies the classes' actual type. – TaegumyType
is set toChildType.Invalid
in the base class. The static initializers in the child classes set it to a valid type (e.g.ChildType.ChildA
orChildType.ChildB
). Once again, this works when running as a regular application. It's only skipped when running this one test via JUnit. – TaegumyType
a member ofBase
then? – JehiasmyType
in static initializers as they called only once on class loading, and this is not quite predictable. you can add abstract methodType getType()
in base class and implement it in Child classes. – Cooe