Vova Iatsyk Vova Iatsyk - 2 months ago 37
Java Question

Resolve profile based properties file into spring tests

Into my spring

RootConfig
class I use properties file based on my spring profile:

@Configuration
@PropertySource("classpath:properties/app.properties")
@PropertySource("classpath:properties/app-${spring.profiles.active}.properties")
@ComponentScan(...)
public class RootConfig {

@Bean // just because you will ask about it
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}

}


Now I want to write test class that use such configuration:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = RootConfig.class)
public class RootConfigTest {

@Test
public void testContext() throws Exception {
assertTrue(true);
}

}


But my context is failed to start:
java.lang.IllegalStateException: Failed to load ApplicationContext
because

Could not resolve placeholder 'spring.profiles.active' in string value "classpath:properties/app-${spring.profiles.active}.properties"


And this is web application, so originally my spring profile configured at:

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.setInitParameter("spring.profiles.active", getSpringProfilesActive());
}

}


getSpringProfilesActive()
- is a static method, that read System property and not depend on context.

Answer

In your case, servletContext.setInitParameter("spring.profiles.active", "dev") is set as part of WebAppInitializer which is not getting invoked when you run your test case, set the spring.profiles.active to dev before invoking the test, as follows:

import java.util.Properties;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = RootConfig.class)
public class RootConfigTest {

    @BeforeClass
    public static void setSystemProperty() {
        Properties properties = System.getProperties();
        properties.setProperty("spring.profiles.active", "dev");
    }

    @Test
    public void testContext() throws Exception {
        assertTrue(true);
    }

}