Trying some variants of rules creation in a groovy file, I have come to the thought, that @Rule doesn't describe DECLARATION, but ASSIGNMENT. So, the runner, when loading the test, tries every rule for the correct assignment.
//Correct variants:
@Rule
public ErrorCollector collector1= new ErrorCollector();
public ErrorCollector collector2= null;
@Rule
collector2= new ErrorCollector();
public ErrorCollector collector3;
@Rule
collector3= new ErrorCollector();
// incorrect variants:
@Rule
public ErrorCollector collector4= null;
@Rule
public ErrorCollector collector5;
@Rule
public ErrorCollector collector5=somethingThatIsNotRule;
@Rule
public ErrorCollector collector5=anotherRule;
But, then I came to some paradoxial variants:
//these lines are not only taken by the runner, but also passed without errors:
public ErrorCollector collector6;
{
@Rule
collector6= null;
}
public ErrorCollector collector7=null;
{
@Rule
collector7= null;
}
What is the logic of it?
It seems as a bug in Runner - the runner makes an excessive check before constructing the test.
In Java, the JUnit runner checks that the
@Rule
annotation is applied to a public non-static field or public non-static method which returns either a TestRule or MethodRule.If there is
@Rule
annotation on a field or method, then the value must be a non-null value or you'll get a NullPointerException during execution of the test.Your example is more complicated than that because Groovy is a dynamic language, so it does its checking at runtime, not compile time. I suspect that collector2 and collector3 aren't actually doing anything. The
@Rule
annotation doesn't apply to the field.For your paradoxes, again, the
@Rule
annotation isn't actually applying to the field.I suspect your confusion comes from the fact that Groovy doesn't complain about the usage of
@Rule
on something that isn't a field or method (whereas Java would). It may not complain, but JUnit will ignore such an annotation.