Initialization in JUnit @Before methods
A JUnit test case may have a method annotated with @Before that initializes fields. (In JUnit 3, a method named setUp is used.)
Given such code, the Nullness Checker issues a warning:
error: [initialization.fields.uninitialized] the constructor does not initialize fields
These errors could be eliminated if the Checker Framework assumes that any method annotated with @Before is executed on every new instance, at the end of the constructor.
This heuristic is sound if the class is only used by JUnit.
This heuristic is unsound in general, because a class that has a @Before-annotated method could be used in ways other than as a JUnit test case. In particular, client code could instantiate the class, not call the @Before-annotated method, and call some other method.
Despite the unsoundness, the heuristic (or some other fix) is worth considering, because @Before methods that initialize fields are common and lead to many Nullness Checker warnings.
To work around this, one can avoid compiling the tests by passing -Dmaven.test.skip=true to Maven, for example
mvn package -Dmaven.test.skip=true
To achieve soundness, it would be necessary to ensure that the class is not instantiated outside JUnit.
- all constructors are private (and some constructor exists so that there is no default constructor)
- the class is final so no subclasses can be instantiated either
Does JUnit still work at that point?
Could it make sense to associate a state machine with a class and validate w.r.t. to that instead of the default constructor-initiated state machine? Beam has adopted some annotation-driven APIs with a sequence like (@Setup, (@StartBundle; @ProcessElement*; @FinishBundle); @Teardown)
Is there any established work in the Java verification lit to express this sort of state machine?
This feature would be helpful