#java #spring #spring-boot #spring-test
Вопрос:
У меня есть несколько классов интеграционных тестов, все они импортируют конфигурацию из одного @Configuration
класса, который externalApi
определенным образом создает издевательский компонент (для иллюстрации, передавая true
в качестве аргумента конструктора).:
@Configuration public class TestConfig { @Bean @Primary ExternalApi externalApi() { return new MockExternalApi(true); // lt;-- true by default for all test classes } }
Но для конкретного класса интеграционного теста мне нужно создать этот компонент по-другому (скажем, передать false
в качестве аргумента конструктора). Для этого я попытался использовать @TestConfiguration
в статическом внутреннем классе следующее:
@RunWith(SpringRunner.class) @SpringBootTest("spring.main.allow-bean-definition-overriding=true") @Import(TestConfig.class) @ActiveProfiles("test") public class ExampleIT { @TestConfiguration public static class ExternalApiConfig { @Bean @Primary ExternalApi externalApi() { return new MockExternalApi(false); // lt;-- false for this particular test class } } @Test public void someTest() {...} }
Это работает, однако, при одновременном выполнении всех моих классов интеграционных тестов ( maven verify
например), когда все тестовые классы выполняются после этого одного перерыва. Поскольку они используют один и тот же контекст, кажется, что после изменения этого компонента он остается измененным (т. Е. с этим false
аргументом) и для всех последующих тестовых классов. Я попытался исправить это, используя @DirtiesContext
на уровне класса, чтобы контекст можно было перезагрузить для следующих тестовых классов, но это не сработало.
Есть ли способ достичь того, что я пытаюсь сделать?
Примечание: Если я добавлю тот же @TestConfiguration
самый статический внутренний класс ко всем другим моим классам интеграционного теста, сделав обратное, т. Е. создав externalApi
компонент обратно с true
помощью arg, то все они будут работать. Но я, конечно, не хочу этого делать.
Комментарии:
1. Как насчет удаления
@Import(TestConfig.class)
для этого конкретного теста? Или там есть несколько определений компонентов? Кроме того, не могли бы вы попробовать поexternalApi
-другому назвать этот интеграционный тест, можетinnerExternalApi
быть . Каким-то образом механизм кэширования контекста Spring должен определить, что вы работаете здесь с другим контекстом.
Ответ №1:
Это похоже на ошибку в весеннем бегуне; @TestConfiguration
ее не следует распространять. В качестве обходного пути попробуйте добавить @DirtiesContext
в свой тест принудительное обновление.
Ответ №2:
Это работает:
Класс конфигурации:
// @TestConfiguration // Put this class in a separate file // NB! Do not annotate this class with @TestConfiguration, // or else the configuration will be propagated to other tests! public class UkvServiceTestContextConfiguration {
Набор тестов, использующий эту конфигурацию:
@RunWith(SpringRunner.class) // NB! Do not use a nested static configuration class, use an external configuration class. // Nested static configuration class gets propagated to other tests! @Import(UkvServiceTestContextConfiguration.class)
публичный класс UkvServiceTest {