Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

spring - Java custom Annotation aggregate multiple annotations

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...