diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java index 6b685be7b66..aff052911b6 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootContextLoader.java @@ -19,10 +19,8 @@ package org.springframework.boot.test.context; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; -import java.util.Map; import java.util.Set; import org.springframework.beans.BeanUtils; @@ -36,7 +34,6 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.SpringVersion; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.StandardEnvironment; import org.springframework.test.context.ContextConfigurationAttributes; import org.springframework.test.context.ContextCustomizer; @@ -90,8 +87,6 @@ public class SpringBootContextLoader extends AbstractContextLoader { if (!ObjectUtils.isEmpty(config.getActiveProfiles())) { setActiveProfiles(environment, config.getActiveProfiles()); } - Map properties = getEnvironmentProperties(config); - addProperties(environment, properties); application.setEnvironment(environment); List> initializers = getInitializers(config, application); @@ -135,29 +130,19 @@ public class SpringBootContextLoader extends AbstractContextLoader { + StringUtils.arrayToCommaDelimitedString(profiles)); } - protected Map getEnvironmentProperties( - MergedContextConfiguration config) { - Map properties = new LinkedHashMap(); + protected String[] getInlinedProperties(MergedContextConfiguration config) { + ArrayList properties = new ArrayList(); // JMX bean names will clash if the same bean is used in multiple contexts disableJmx(properties); - properties.putAll(TestPropertySourceUtils - .convertInlinedPropertiesToMap(config.getPropertySourceProperties())); + properties.addAll(Arrays.asList(config.getPropertySourceProperties())); if (!isEmbeddedWebEnvironment(config)) { - properties.put("server.port", "-1"); + properties.add("server.port=-1"); } - return properties; + return properties.toArray(new String[properties.size()]); } - private void disableJmx(Map properties) { - properties.put("spring.jmx.enabled", "false"); - } - - private void addProperties(ConfigurableEnvironment environment, - Map properties) { - // @IntegrationTest properties go before external configuration and after system - environment.getPropertySources().addAfter( - StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, - new MapPropertySource("integrationTest", properties)); + private void disableJmx(List properties) { + properties.add("spring.jmx.enabled=false"); } private List> getInitializers( @@ -166,8 +151,8 @@ public class SpringBootContextLoader extends AbstractContextLoader { for (ContextCustomizer contextCustomizer : config.getContextCustomizers()) { initializers.add(new ContextCustomizerAdapter(contextCustomizer, config)); } - initializers.add(new PropertySourceLocationsInitializer( - config.getPropertySourceLocations())); + initializers.add(new TestPropertySourcesInitializer( + config.getPropertySourceLocations(), getInlinedProperties(config))); initializers.addAll(application.getInitializers()); for (Class> initializerClass : config .getContextInitializerClasses()) { @@ -258,21 +243,27 @@ public class SpringBootContextLoader extends AbstractContextLoader { } /** - * {@link ApplicationContextInitializer} to setup test property source locations. + * {@link ApplicationContextInitializer} to set up test property sources. */ - private static class PropertySourceLocationsInitializer + private static class TestPropertySourcesInitializer implements ApplicationContextInitializer { private final String[] propertySourceLocations; - PropertySourceLocationsInitializer(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); } } diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java index 2be54590afc..490e264359c 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java @@ -206,7 +206,9 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr Class testClass = mergedConfig.getTestClass(); String[] properties = getProperties(testClass); if (!ObjectUtils.isEmpty(properties)) { - propertySourceProperties.addAll(Arrays.asList(properties)); + // Added first so that inlined properties from @TestPropertySource take + // precedence + propertySourceProperties.addAll(0, Arrays.asList(properties)); } if (getWebEnvironment(testClass) == WebEnvironment.RANDOM_PORT) { propertySourceProperties.add("server.port=0"); diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestPropertyLocationTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestPropertyLocationTests.java deleted file mode 100644 index c1035291289..00000000000 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestPropertyLocationTests.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 javax.annotation.PostConstruct; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.core.env.Environment; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link SpringBootTest} with {@link TestPropertySource} locations. - * - * @author Phillip Webb - */ -@RunWith(SpringRunner.class) -@DirtiesContext -@SpringBootTest(webEnvironment = WebEnvironment.NONE, properties = "value1=123") -@TestPropertySource(properties = "value2=456", locations = "classpath:/test-property-source-annotation.properties") -public class SpringBootTestPropertyLocationTests { - - @Autowired - private Environment environment; - - @Test - public void loadedProperties() throws Exception { - assertThat(this.environment.getProperty("value1")).isEqualTo("123"); - assertThat(this.environment.getProperty("value2")).isEqualTo("456"); - assertThat(this.environment.getProperty("annotation-referenced")) - .isEqualTo("fromfile"); - } - - @Configuration - static class Config { - - @Value("${value1}") - private String value1; - - @Value("${value2}") - private String value2; - - @Value("${annotation-referenced}") - private String annotationReferenced; - - @PostConstruct - void checkValues() { - assertThat(this.value1).isEqualTo("123"); - assertThat(this.value2).isEqualTo("456"); - assertThat(this.annotationReferenced).isEqualTo("fromfile"); - } - - @Bean - public static PropertySourcesPlaceholderConfigurer propertyPlaceholder() { - return new PropertySourcesPlaceholderConfigurer(); - } - - } - -} diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWithTestPropertySourceTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWithTestPropertySourceTests.java new file mode 100644 index 00000000000..5437a61c1a4 --- /dev/null +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/context/SpringBootTestWithTestPropertySourceTests.java @@ -0,0 +1,113 @@ +/* + * 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.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for using {@link SpringBootTest} with {@link TestPropertySource}. + * + * @author Phillip Webb + * @author Andy Wilkinson + */ +@RunWith(SpringRunner.class) +@DirtiesContext +@SpringBootTest(webEnvironment = WebEnvironment.NONE, properties = { + "boot-test-inlined=foo", "b=boot-test-inlined", "c=boot-test-inlined" }) +@TestPropertySource(properties = { "property-source-inlined=bar", + "a=property-source-inlined", + "c=property-source-inlined" }, locations = "classpath:/test-property-source-annotation.properties") +public class SpringBootTestWithTestPropertySourceTests { + + @Autowired + private Config config; + + @Test + public void propertyFromSpringBootTestProperties() { + assertThat(this.config.bootTestInlined).isEqualTo("foo"); + } + + @Test + public void propertyFromTestPropertySourceProperties() { + assertThat(this.config.propertySourceInlined).isEqualTo("bar"); + } + + @Test + public void propertyFromTestPropertySourceLocations() { + assertThat(this.config.propertySourceLocation).isEqualTo("baz"); + } + + @Test + public void propertyFromPropertySourcePropertiesOverridesPropertyFromPropertySourceLocations() { + assertThat(this.config.propertySourceInlinedOverridesPropertySourceLocation) + .isEqualTo("property-source-inlined"); + } + + @Test + public void propertyFromBootTestPropertiesOverridesPropertyFromPropertySourceLocations() { + assertThat(this.config.bootTestInlinedOverridesPropertySourceLocation) + .isEqualTo("boot-test-inlined"); + } + + @Test + public void propertyFromPropertySourcePropertiesOverridesPropertyFromBootTestProperties() { + assertThat(this.config.propertySourceInlinedOverridesBootTestInlined) + .isEqualTo("property-source-inlined"); + } + + @Configuration + static class Config { + + @Value("${boot-test-inlined}") + private String bootTestInlined; + + @Value("${property-source-inlined}") + private String propertySourceInlined; + + @Value("${property-source-location}") + private String propertySourceLocation; + + @Value("${a}") + private String propertySourceInlinedOverridesPropertySourceLocation; + + @Value("${b}") + private String bootTestInlinedOverridesPropertySourceLocation; + + @Value("${c}") + private String propertySourceInlinedOverridesBootTestInlined; + + @Bean + public static PropertySourcesPlaceholderConfigurer propertyPlaceholder() { + return new PropertySourcesPlaceholderConfigurer(); + } + + } + +} diff --git a/spring-boot-test/src/test/resources/test-property-source-annotation.properties b/spring-boot-test/src/test/resources/test-property-source-annotation.properties index dcb1aed351b..049c77667ec 100644 --- a/spring-boot-test/src/test/resources/test-property-source-annotation.properties +++ b/spring-boot-test/src/test/resources/test-property-source-annotation.properties @@ -1 +1,3 @@ -annotation-referenced=fromfile +property-source-location=baz +a=property-source-location +b=property-source-location