Configure test property sources before ConfigFileApplicationListener runs

Previously, SpringBootContextLoader configured the environment with the
test property sources using an ApplicationContextInitializer. This was
because TestPropertySourceUtils did not provide a method to directly
configure the environment using properties files, it had to be done
via an application context. An unwanted side-effect of this was that
the test property sources were not being configured before
ConfigFileApplicationListener examined the environment to determine the
name and locations of the files that it should be loading.

This commit takes advantage of a new method that was added to
TestPropertySourceUtils which allows properties files to be added
directly to the environment without using an application context. This
means that the use of the ApplicationContextInitializer can be removed
and the test property sources can be applied to the environment before
the application context is created.

Closes gh-5728
pull/5745/head
Andy Wilkinson 9 years ago
parent 0cfcbeb40e
commit 601791c664

@ -31,11 +31,11 @@ import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.SpringVersion;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextLoader;
@ -88,6 +88,13 @@ public class SpringBootContextLoader extends AbstractContextLoader {
if (!ObjectUtils.isEmpty(config.getActiveProfiles())) {
setActiveProfiles(environment, config.getActiveProfiles());
}
TestPropertySourceUtils.addPropertiesFilesToEnvironment(environment,
application.getResourceLoader() == null
? new DefaultResourceLoader(getClass().getClassLoader())
: application.getResourceLoader(),
config.getPropertySourceLocations());
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(environment,
getInlinedProperties(config));
application.setEnvironment(environment);
List<ApplicationContextInitializer<?>> initializers = getInitializers(config,
application);
@ -152,8 +159,6 @@ public class SpringBootContextLoader extends AbstractContextLoader {
for (ContextCustomizer contextCustomizer : config.getContextCustomizers()) {
initializers.add(new ContextCustomizerAdapter(contextCustomizer, config));
}
initializers.add(new TestPropertySourcesInitializer(
config.getPropertySourceLocations(), getInlinedProperties(config)));
initializers.addAll(application.getInitializers());
for (Class<? extends ApplicationContextInitializer<?>> initializerClass : config
.getContextInitializerClasses()) {
@ -243,38 +248,6 @@ public class SpringBootContextLoader extends AbstractContextLoader {
}
/**
* {@link ApplicationContextInitializer} to set up test property sources.
*/
private static class TestPropertySourcesInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
private final String[] propertySourceLocations;
private final String[] inlinedProperties;
TestPropertySourcesInitializer(String[] propertySourceLocations,
String[] inlinedProperties) {
this.propertySourceLocations = propertySourceLocations;
this.inlinedProperties = inlinedProperties;
}
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
TestPropertySourceUtils.addPropertiesFilesToEnvironment(applicationContext,
this.propertySourceLocations);
TestPropertySourceUtils.addInlinedPropertiesToEnvironment(applicationContext,
this.inlinedProperties);
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 10;
}
}
/**
* Adapts a {@link ContextCustomizer} to a {@link ApplicationContextInitializer} so
* that it can be triggered via {@link SpringApplication}.

@ -0,0 +1,55 @@
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.test.context;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@SpringBootTest} with a custom config name
*
* @author Andy Wilkinson
*/
@RunWith(SpringRunner.class)
@SpringBootTest(properties = "spring.config.name=custom-config-name")
public class SpringBootTestCustomConfigNameTests {
@Value("${test.foo}")
private String foo;
@Test
public void propertyIsLoadedFromConfigFileWithCustomName() {
assertThat(this.foo).isEqualTo("bar");
}
@Configuration
static class TestConfiguration {
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
}
Loading…
Cancel
Save