代码之家  ›  专栏  ›  技术社区  ›  hammerfest

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

  •  13
  • hammerfest  · 技术社区  · 9 年前

    我们有一个基于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 {
        ...
    

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

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

    2 回复  |  直到 9 年前
        1
  •  16
  •   Andy    9 年前

    在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());
                }
            }
    
        }
    }
    
        2
  •  4
  •   Aaron Digulla    9 年前

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

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

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