Reload or refresh a Spring application context inside a test method?
applicationcontext, java, spring, spring-test, testng
Solution
By design, programmatic refreshing of an `ApplicationContext` is not explicitly supported by the Spring TestContext Framework. Furthermore, it is not intended that a test method refresh a context.
Thus I would recommend that you reassess your need for a refresh and consider alternatives like placing test methods that require a different set of active profiles in a dedicated test class.
In summary, `@ActiveProfiles` supports declarative configuration (via `value` and `profiles` attributes) and programmatic configuration (via the `resolver` attribute) of the active profiles for tests, but only at the test class level (not at the method level). Another option is to implement an `ApplicationContextInitializer` and configure that via `@ContextConfiguration(initializers=...)`.
The only other way to affect the `ApplicationContext` before it is refreshed is to implement a `SmartContextLoader` or extend one of the provided classes and configure it via `@ContextConfiguration(loader=...)`. For example, `AbstractGenericContextLoader.customizeContext()` allows one to "customize the `GenericApplicationContext` created by the loader after bean definitions have been loaded into the context but before the context is refreshed."
Best regards,
Sam (author of the Spring TestContext Framework)
Problem
I need to change the Spring profiles that are active in my applicationContext within a single method of my test class, and to do so I need to run one line of code before refreshing the contest because I am using a ProfileResolver. I have tried the following: ``` @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 } } ``` But I get: ``` java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once ``` DirtiesContext does not work for me because it is run AFTER class/method execution, not before, and I need to execute a line of code prior to running the refresh/reload anyway. Any suggestions? I tried to have a look through the listeners/hooks that are being run, but I didn't see an obvious location to insert myself to achieve this behavior.