Использовать другую конфигурацию контекста теста 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 ответов


Я использую эти подходы, когда мне нужно решить это:

  • вручную создайте контекст в методе установки вместо использования аннотаций.
  • переместите общий тестовый код в базовый класс и расширьте его. Это позволяет мне запускать тесты с разными контекстами spring.
  • смесь двух выше. Затем базовый класс содержит методы построения контекстов spring из фрагментов (которые расширения могут переопределять). Это также позволяет мне переопределять тестовые случаи которые не имеют смысла или делают дополнительную работу до / после в некоторых тестах.

имейте в виду, что аннотации решают только общие случаи. Вам придется воспроизвести некоторые или все их работы, когда вы покинете общую почву.


с предложением Аарона вручную создать контекст я не мог найти хороших примеров, поэтому, потратив некоторое время на его работу, я подумал, что опубликую простую версию кода, который я использовал, если это поможет кому-то еще:

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

    }
}