问题
I am looking for a way to simplify the following code.
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {
// My configuration classes
})
public class MyServiceTest {
@Autowired
private MyService service;
@Test
public void myTest() {
Assert.assertTrue(service != null);
}
}
I have many configuration classes and I don't want to put them into each test class. So I got the idea to create my own annotation:
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {
// My configuration classes
})
public @interface IntegrationTests {
}
I try to use it in the following way:
@IntegrationTests
public class MyServiceTest {
@Autowired
private MyService service;
@Test
public void myTest() {
Assert.assertTrue(service != null);
}
}
But it doesn't work. Any idea?
回答1:
You can place these annotation on a superclass:
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {
// My configuration classes
})
public abstract class AbstractIntegrationTest { ... }
.
public class MyServiceTest extends AbstractIntegrationTest { ... }
This approach also allows you to declare common @Autowired
dependencies in the base class and customize @ContextConfiguration
classes in concrete tests.
回答2:
The reason your custom composed annotation did not work is that JUnit does not support @RunWith
as a meta-annotation. Thus, when you compose your annotation as follows...
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { /* configuration classes */ })
public @interface IntegrationTests {
}
... it is JUnit that cannot see that you want to use the SpringJUnit4ClassRunner
.
Spring Framework 4.0 and greater should have no problem seeing the declarations of @WebAppConfiguration
and @ContextConfiguration
used as meta-annotations.
In other words, the following should work for you:
@WebAppConfiguration
@ContextConfiguration(classes = { /* configuration classes */ })
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface IntegrationTests {
}
@RunWith(SpringJUnit4ClassRunner.class)
@IntegrationTests
public class MyServiceTest {
@Autowired
private MyService service;
@Test
public void myTest() {
assertNotNull(service);
}
}
As an alternative, you can use an abstract
base test class as recommended by axtavt.
Regards,
Sam (author of the Spring TestContext Framework)
来源:https://stackoverflow.com/questions/24653804/java-annotations-code-simplifications