Reload or refresh a Spring application context inside a test method?

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)


There's a nice little hack to trigger a context refresh - to use org.springframework.cloud.context.refresh.ContextRefresher.

I'm not 100% sure this method will suite you: it requires a spring-cloud-context dependency. However, this may be added just as a test dependency and not leak into production classpath.

To use this refresher you also need to import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration configuration, which adds a RefreshScope scope to your applicationContext which is actually doing the job under the hood.

So, modify test as follows:

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
import org.springframework.cloud.context.refresh.ContextRefresher;    
// your other imports


@WebAppConfiguration
@ContextConfiguration(locations = {"/web/WEB-INF/spring.xml"}, classes = RefreshAutoConfiguration.class)
@ActiveProfiles(resolver = BaseActiveProfilesResolverTest.class)
public class ControllerTest extends AbstractTestNGSpringContextTests {

    @Autowired
    private ContextRefresher contextRefresher;

    @Test
    public void test() throws Exception {
        // doSmth before
        contextRefresher.refresh();
        // context is refreshed - continue testing
    }

}