1

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.

Gangnus
  • 24,044
  • 16
  • 90
  • 149
  • Not possible, if you take a look at `@Rule` annotation, it has targets `FILED`&`METHOD`. Your paradoxial variant should not compile, because essentially it's a field assignment inside instance initializer block, not field declaration. – denis.solonenko Apr 11 '13 at 07:43
  • well, I can only assume there is a bug in Eclipse compiler. This piece of code does not compile in IntelliJ Idea – denis.solonenko Apr 11 '13 at 07:54
  • Yes, sorry, I have forgotten to mention that it was all done in groovy file - groovy is not so strict as java - edited. – Gangnus Apr 11 '13 at 07:58

1 Answers1

1

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.

collector4 => NullPointerException
collector5 => same as collector5
collector5a => when you execute, I suspect Groovy doesn't find the
               expected methods on your somethingThatIsNotRule, or
               you're getting a ClassCastException or something similar.
collector5b => same as 5b for anotherRule

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.

Matthew Farwell
  • 60,889
  • 18
  • 128
  • 171
  • I have noticed it already. Yes, for collectors 6 and 7 the collectors in {} are new ones. BTW, in my Groovy code the ErrorCollector works OK on a static field. And yet I'll have one more question http://stackoverflow.com/questions/15966146/why-does-errorcollector-demands-for-assignment-at-the-moment-of-declaration. And please, could you check the tag def: http://stackoverflow.com/edit-tag-wiki/90826. Thank you. – Gangnus Apr 12 '13 at 08:17