对不同的测试方法使用不同的Spring测试上下文配置

我们有一个基于Spring的JUnit测试类,它使用内部测试上下文配置类

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = ServiceTest.Config.class) public class ServiceTest { @Test public void someTest() { ... @Configuration @PropertySource(value = { "classpath:application.properties" }) @ComponentScan({ "..." }) public static class Config { ... 

最近已向Service类引入了新function,应将相关测试添加到ServiceTest中。 然而,这些还需要创建一个不同的测试上下文配置类(现有Config类的内部相当复杂,如果可能的话,将其更改为新旧测试似乎非常困难)

有没有办法实现一个测试类中的某些测试方法将使用一个配置类,而其他方法将使用另一个? @ContextConfiguration似乎只适用于类级别,因此解决方案可能是为新测试创建另一个测试类,它将使用自己的上下文配置类; 但这意味着通过两个不同的测试类覆盖相同的Service类

当我必须解决这个问题时,我会使用这些方法:

  • 在设置方法中手动构建上下文而不是使用注释。
  • 将公共测试代码移动到基类并扩展它。 这允许我使用不同的弹簧上下文运行测试。
  • 以上两者的混合。 然后,基类包含从片段构建弹簧上下文的方法(扩展可以覆盖)。 这也允许我覆盖那些没有意义的测试用例或在某些测试中做额外的前/后工作。

请记住,注释只能解决一般情况。 当你离开共同点时,你将不得不复制他们的部分或全部工作。

有了Aaron关于手动构建上下文的建议,我找不到任何好的例子,所以在花了一些时间让它工作之后,我想我会发布一个简单版本的代码,以防它帮助其他人:

 class MyTest { @Autowired private SomeService service; @Autowired private ConfigurableApplicationContext applicationContext; public void init(Class testClass) throws Exception { TestContextManager testContextManager = new TestContextManager(testClass); testContextManager.prepareTestInstance(this); } @After public void tearDown() throws Exception { applicationContext.close(); } @Test public void test1() throws Exception { init(ConfigATest.class); service.doSomething(); // assert something } @Test public void test2() throws Exception { init(ConfigBTest.class); service.doSomething(); // assert something } @ContextConfiguration(classes = { ConfigATest.ConfigA.class }) static class ConfigATest { static class ConfigA { @Bean public SomeService someService() { return new SomeService(new A()); } } } @ContextConfiguration(classes = { ConfigBTest.ConfigB.class }) static class ConfigBTest { static class ConfigB { @Bean public SomeService someService() { return new SomeService(new B()); } } } }