Im writing a TestCases for my RestControllers
For each ControllerTest calss I use the following annotations
@WebAppConfiguration
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebConfig.class, TestAppConfig.class})
So, I decided to define my own annotation witch contain all those annotations like this
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@WebAppConfiguration
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebConfig.class, TestAppConfig.class})
public @interface ControllerTest {
}
Then, I used only one annotation for all my ControllerTest classes
@ControllerTest
public class XXControllerTest {
}
After this modification the tests failed with
java.lang.IllegalArgumentException: WebApplicationContext is required
    at org.springframework.util.Assert.notNull(Assert.java:115)
And to make it work again it required me to add the @RunWith(SpringJUnit4ClassRunner.class) to the Test class
@ControllerTest
@RunWith(SpringJUnit4ClassRunner.class)
public class XXControllerTest {
}
My question is why my @ControllerTest annotation doesn't work while its contain the @RunWith(SpringJUnit4ClassRunner.class) annotation? is there anything special about the @RunWith annotation? or did I miss something?
PS: I use the same approach for Spring config classes and they work just fine.
It is also possible to use multiple annotations on the same declaration: @Author(name = "Jane Doe") @EBook class MyClass { ... } If the annotations have the same type, then this is called a repeating annotation: @Author(name = "Jane Doe") @Author(name = "John Smith") class MyClass { ... }
You can repeat an annotation anywhere that you would use a standard annotation. For example, you have a class for handling unauthorized access exceptions.
They all act the same because they are all composed annotations with @Component as a meta-annotation for each of them.
Annotation is defined like a ordinary Java interface, but with an '@' preceding the interface keyword (i.e., @interface ). You can declare methods inside an annotation definition (just like declaring abstract method inside an interface). These methods are called elements instead.
This mechanism, where you can have "meta-annotations" that are themselves annotated with other annotations, which then apply to the class on which you put your meta-annotation, is something that is specific to the Spring Framework. It is not a standard feature of Java annotations.
It doesn't work because JUnit does not understand this mechanism. The @RunWith annotation is a JUnit annotation. JUnit does not understand that it should look at the annotations that are on your @ControllerTest meta-annotation.
So, this mechanism works with annotations that are processed by Spring, but not with annotations that are processed by other tools such as JUnit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With