2016-01-29 40 views
5
使用不同的Spring测试上下文配置

我们这是利用内部测试情况下配置类对于不同的测试方法

@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 { 
    ... 

新的功能已经被最近推出的服务类基于Spring的JUnit测试类,为此,有关的测试应该被添加到ServiceTest。然而,这些还需要创建不同的测试环境配置类(现有Config类的内部相当复杂,并且将其更改为服务于新旧测试似乎是极其困难的,如果可能的话,似乎是极其困难的)

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

回答

1

我使用这些方法时,我已经覆盖到解决这个问题:

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

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

+0

但是,如果我们手动设置在内部,Autowired注入是否在基类中工作? – pinkpanther

+0

@pinkpanther:你正在测试设置与测试代码混淆。测试设置不使用'@ Autowired'。当我可以的时候,我在测试中避免注入:它减慢了测试的速度,并且更难以看出发生了什么。当IDE支持“当我运行测试时向我显示注入的内容”时,我会改变主意。 –

4

随着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()); 
      } 
     } 

    } 
} 
相关问题