@TestPropertySource doesn't work for JUnit test with AnnotationConfigContextLoader in Spring 1.2.6
Turns out the best way (until Spring fixes this oversight) is to a PropertySourcesPlaceholderConfigurer
that will bring in test.properties (or whatever you want) and @Import
or extend that @Configuration
.
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import java.io.IOException;
@Configuration
public class PropertyTestConfiguration {
@Bean
public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() throws IOException {
final PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setLocations(ArrayUtils.addAll(
new PathMatchingResourcePatternResolver().getResources("classpath*:application.properties"),
new PathMatchingResourcePatternResolver().getResources("classpath*:test.properties")
)
);
return ppc;
}
}
This allows you to define defaults in application.properties and override them in test.properties. Of course, if you have multiple schemes, then you can configure the PropertyTestConfiguration
class as necessary.
And use this in a unit test.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class PropertyTests {
@Value("${elastic.index}")
String index;
@Configuration
@Import({PropertyTestConfiguration.class})
static class ContextConfiguration {
}
}
I used the locations
property of @TestPropertySource
to override (or add) properties.
This worked for me (spring 4.2.4):
@TestPropertySource(locations = {
"classpath:test.properties",
"classpath:test-override.properties" })
But overriding properties like below didn't:
@TestPropertySource(
locations = {"classpath:test.properties"},
properties = { "key=value" })
Even though the javadoc says that those properties have highest precedence. A bug maybe?
Update
The bug should be fixed in Spring boot version 1.4.0 and up. See the commit which closes the issue. By now, properties declared in the presented way should get precedence.
Your use of @Value requires a PropertySourcesPlaceholderConfigurer bean to resolve ${...}
placeholders. See the accepted answer here: @Value not set via Java-configured test context