Перезагрузить или обновить контекст приложения Spring внутри метода тестирования?

мне нужно изменить профили Spring, которые активны в моем applicationContext в рамках одного метода моего тестового класса, и для этого мне нужно запустить одну строку кода перед обновлением конкурса, потому что я использую ProfileResolver. Я попробовал следующее:

@WebAppConfiguration
@ContextConfiguration(locations = {"/web/WEB-INF/spring.xml"})
@ActiveProfiles(resolver = BaseActiveProfilesResolverTest.class)
public class ControllerTest extends AbstractTestNGSpringContextTests {
    @Test
    public void test() throws Exception {
        codeToSetActiveProfiles(...);
        ((ConfigurableApplicationContext)this.applicationContext).refresh();
        ... tests here ...
        codeToSetActiveProfiles(... back to prior profiles ...);
        ... ideally refresh/reload the context for future tests
    }
}

а я:

java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once

DirtiesContext не работает для меня, потому что он запускается после выполнения класса / метода, а не раньше, и мне нужно выполнить строку кода до запуска обновить/обновить в любом случае.

какие предложения? Я попытался просмотреть слушателей / крючки, которые запускаются, но я не видел очевидного места для вставки себя для достижения этого поведения.

2 ответов


по дизайну, программное обновление ApplicationContext явно не поддерживается Spring Testcontext Framework. Кроме того, не предполагается, что тестовый метод обновляет контекст.

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

в целом, @ActiveProfiles поддерживает декларативный конфигурация (через value и profiles атрибуты) и программ настройки (через resolver атрибут) активных профилей для тестов, но только на уровне класса теста (не на уровне метода). Другой вариант-реализовать ApplicationContextInitializer и настройте это через @ContextConfiguration(initializers=...).

единственный способ повлиять на ApplicationContext до он обновляется, чтобы реализовать SmartContextLoader или расширить один из предоставленных классов и настроить его через @ContextConfiguration(loader=...). Например, AbstractGenericContextLoader.customizeContext() позволяет "настраивать GenericApplicationContext создано загрузчиком после определения bean были загружены в контекст, но до контекст обновляется."

С уважением,

Sam (автор Spring Testcontext Framework)


не все контекстные приложения поддерживают несколько refresh. Согласно javadoc для AbstractRefreshableApplicationContext только подклассы it или of AbstractRefreshableWebApplicationContext принимать refresh более одного раза ... и GenericApplicationContext ни в одном из них.

вы должны использовать другой класс ApplicationContext для поддержки "горячей" обновить.

Edit:

как вы используете @ContextConfiguration аннотация, вы должны использовать пользовательский ContextLoader или SmartContextLoader реализация, чтобы заставить spring использовать менее глупый ApplicationContext. Но я никогда ... нашел чистый и аккуратный способ к этому. Поэтому, когда мне нужно XmlWebApplicationContext в моих тестовых классах я не использую @ContextConfiguration но создайте и обновите мой контекст вручную на @Before метод или в начале теста.

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