简体   繁体   English

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

[英]Use different Spring test context configuration for different test methods

We have a Spring based JUnit test class which is utilizing an inner test context configuration class 我们有一个基于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 {
    ...

New functionalities have been recently introduced to the Service class, for which the concerned tests should be added to ServiceTest. 最近已向Service类引入了新功能,应将相关测试添加到ServiceTest中。 However these would also require a different test context configuration class to be created (the internals of the existing Config class are fairly complex and change it to serve both old and new tests seems to be be extremely difficult if possible at all) 但是,这些还需要创建一个不同的测试上下文配置类(现有Config类的内部相当复杂,如果可能的话,将其更改为新旧测试似乎非常困难)

Is there a way to achieve that certain test methods in one test class would use one config class and other methods would use another? 有没有办法实现一个测试类中的某些测试方法将使用一个配置类,而其他方法将使用另一个? @ContextConfiguration seems to be applicable only on class level, so solution could be to create another test class for the new tests which would utilize its own context configuration class; @ContextConfiguration似乎只适用于类级别,因此解决方案可能是为新测试创建另一个测试类,它将使用自己的上下文配置类; but it would mean that the same Service class is being covered via two different test classes 但这意味着通过两个不同的测试类覆盖相同的Service类

With Aaron's suggestion of manually building the context I couldn't find any good examples so after spending some time getting it working I thought I'd post a simple version of the code I used in case it helps anyone else: 有了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());
            }
        }

    }
}

I use these approaches when I'm have to solve this: 当我必须解决这个问题时,我会使用这些方法:

  • Manually build the context in a setup method instead of using annotations. 在设置方法中手动构建上下文而不是使用注释。
  • Move the common test code to a base class and extend it. 将公共测试代码移动到基类并扩展它。 That allows me to run the tests with different spring contexts. 这允许我使用不同的弹簧上下文运行测试。
  • A mix of the two above. 以上两者的混合。 The base class then contains methods to build spring contexts from fragments (which the extensions can override). 然后,基类包含从片段构建弹簧上下文的方法(扩展可以覆盖)。 That also allows me to override test cases which don't make sense or do extra pre/post work in some tests. 这也允许我覆盖那些没有意义的测试用例或在某些测试中做额外的前/后工作。

Keep in mind that annotations only solve generic cases. 请记住,注释只能解决一般情况。 You'll have to replicate some or all of their work when you leave the common ground. 当你离开共同点时,你将不得不复制他们的部分或全部工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM