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