diff --git a/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java b/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java index 150604e72b19..a3c57b97e318 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 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. @@ -19,6 +19,7 @@ import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; +import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -86,6 +87,7 @@ @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited +@Repeatable(TestPropertySources.class) public @interface TestPropertySource { /** diff --git a/spring-test/src/main/java/org/springframework/test/context/TestPropertySources.java b/spring-test/src/main/java/org/springframework/test/context/TestPropertySources.java new file mode 100644 index 000000000000..c59e236823e4 --- /dev/null +++ b/spring-test/src/main/java/org/springframework/test/context/TestPropertySources.java @@ -0,0 +1,51 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context; + + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * {@code @TestPropertySources} is a container for one or more {@link TestPropertySource} + * declarations. + * + *

Note, however, that use of the {@code @TestPropertySources} container is completely + * optional since {@code @TestPropertySource} is a {@linkplain java.lang.annotation.Repeatable + * repeatable} annotation. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +public @interface TestPropertySources { + + /** + * An array of one or more {@link TestPropertySource} declarations. + * + * @return array of {@link TestPropertySource} values. + */ + TestPropertySource[] value(); +} diff --git a/spring-test/src/main/java/org/springframework/test/context/support/TestPropertySourceUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/TestPropertySourceUtils.java index 41574d9169a9..268219495c0a 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/TestPropertySourceUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/TestPropertySourceUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -24,11 +24,14 @@ import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.stream.Collectors; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; @@ -39,13 +42,10 @@ import org.springframework.core.io.support.ResourcePropertySource; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.util.TestContextResourceUtils; -import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; -import static org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptor; - /** * Utility methods for working with {@link TestPropertySource @TestPropertySource} * and adding test {@link PropertySource PropertySources} to the {@code Environment}. @@ -53,6 +53,7 @@ *

Primarily intended for use within the framework. * * @author Sam Brannen + * @author Anatoliy Korovin * @since 4.1 * @see TestPropertySource */ @@ -67,47 +68,59 @@ public abstract class TestPropertySourceUtils { private static final Log logger = LogFactory.getLog(TestPropertySourceUtils.class); - static MergedTestPropertySources buildMergedTestPropertySources(Class testClass) { - Class annotationType = TestPropertySource.class; - AnnotationDescriptor descriptor = findAnnotationDescriptor(testClass, annotationType); - if (descriptor == null) { + + if (!isPresentTestPropertySourceAnnotation(testClass)) { return new MergedTestPropertySources(); } + else { + return mergeTestPropertySources(testClass); + } + } + + private static boolean isPresentTestPropertySourceAnnotation(Class testClass) { + return MergedAnnotations + .from(testClass, MergedAnnotations.SearchStrategy.EXHAUSTIVE) + .get(TestPropertySource.class).isPresent(); + } + + private static MergedTestPropertySources mergeTestPropertySources(Class testClass) { + + List attributesList = resolveTestPropertySourceAttributes( + testClass); - List attributesList = resolveTestPropertySourceAttributes(testClass); String[] locations = mergeLocations(attributesList); String[] properties = mergeProperties(attributesList); + return new MergedTestPropertySources(locations, properties); } private static List resolveTestPropertySourceAttributes(Class testClass) { Assert.notNull(testClass, "Class must not be null"); - List attributesList = new ArrayList<>(); - Class annotationType = TestPropertySource.class; + return MergedAnnotations + .from(testClass, MergedAnnotations.SearchStrategy.EXHAUSTIVE) + .stream(TestPropertySource.class) + .map(TestPropertySourceUtils::makeTestPropertySourceAttribute) + .collect(Collectors.toList()); + } - AnnotationDescriptor descriptor = findAnnotationDescriptor(testClass, annotationType); - Assert.notNull(descriptor, String.format( - "Could not find an 'annotation declaring class' for annotation type [%s] and class [%s]", - annotationType.getName(), testClass.getName())); + private static TestPropertySourceAttributes makeTestPropertySourceAttribute( + MergedAnnotation annotation) { - while (descriptor != null) { - TestPropertySource testPropertySource = descriptor.synthesizeAnnotation(); - Class rootDeclaringClass = descriptor.getRootDeclaringClass(); - if (logger.isTraceEnabled()) { - logger.trace(String.format("Retrieved @TestPropertySource [%s] for declaring class [%s].", + TestPropertySource testPropertySource = annotation.synthesize(); + Class rootDeclaringClass = (Class) annotation.getSource(); + if (logger.isTraceEnabled()) { + logger.trace(String.format( + "Retrieved @TestPropertySource [%s] for declaring class [%s].", testPropertySource, rootDeclaringClass.getName())); - } - TestPropertySourceAttributes attributes = - new TestPropertySourceAttributes(rootDeclaringClass, testPropertySource); - if (logger.isTraceEnabled()) { - logger.trace("Resolved TestPropertySource attributes: " + attributes); - } - attributesList.add(attributes); - descriptor = findAnnotationDescriptor(rootDeclaringClass.getSuperclass(), annotationType); } - return attributesList; + TestPropertySourceAttributes attributes = new TestPropertySourceAttributes( + rootDeclaringClass, testPropertySource); + if (logger.isTraceEnabled()) { + logger.trace("Resolved TestPropertySource attributes: " + attributes); + } + return attributes; } private static String[] mergeLocations(List attributesList) { diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/AnnotationWithTestProperty.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/AnnotationWithTestProperty.java new file mode 100644 index 000000000000..0b52c59c3bf4 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/AnnotationWithTestProperty.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.test.context.TestPropertySource; + +/** + * A custom annotation with properties defined by the {@link TestPropertySource}. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@TestPropertySource(properties = "meta = value from meta-annotation") +public @interface AnnotationWithTestProperty { +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/AnnotationWithTestPropertyInPropertiesFile.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/AnnotationWithTestPropertyInPropertiesFile.java new file mode 100644 index 000000000000..c9a32a632055 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/AnnotationWithTestPropertyInPropertiesFile.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.test.context.TestPropertySource; + +/** + * A custom annotation which defined properties file in the {@link TestPropertySource}. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@TestPropertySource("meta.properties") +public @interface AnnotationWithTestPropertyInPropertiesFile { +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/FooTestProperty.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/FooTestProperty.java new file mode 100644 index 000000000000..94a48f6507ef --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/FooTestProperty.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.test.context.TestPropertySource; + +/** + * A custom annotation with foo property defined by the {@link TestPropertySource}. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@TestPropertySource(properties = "foo = value from meta-annotation") +public @interface FooTestProperty { +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/FooTestPropertyDeclaration.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/FooTestPropertyDeclaration.java new file mode 100644 index 000000000000..a5237c647e90 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/FooTestPropertyDeclaration.java @@ -0,0 +1,29 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + +import org.springframework.test.context.TestPropertySource; + +/** + * Abstract parent class with foo property definition for tests. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@TestPropertySource(properties = "foo = value from parent class") +public abstract class FooTestPropertyDeclaration { +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/ParentClassWithMultipleTestProperties.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/ParentClassWithMultipleTestProperties.java new file mode 100644 index 000000000000..3a176827dcc6 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/ParentClassWithMultipleTestProperties.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + +import org.springframework.test.context.TestPropertySource; + +/** + * Abstract parent class with multiple properties definition for tests. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@TestPropertySource(properties = "first = value from parent class") +@TestPropertySource(properties = "second = value from parent class") +public abstract class ParentClassWithMultipleTestProperties { +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/ParentClassWithTestProperties.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/ParentClassWithTestProperties.java new file mode 100644 index 000000000000..86f792d979a1 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/ParentClassWithTestProperties.java @@ -0,0 +1,30 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + +import org.springframework.test.context.TestPropertySource; + + +/** + * Base class which declare a property by the {@link TestPropertySource} annotation. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@TestPropertySource(properties = "inherited = 12345") +public abstract class ParentClassWithTestProperties { +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritTests.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritTests.java new file mode 100644 index 000000000000..16b59c6d1144 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritTests.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + +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.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + + +/** + * Integration tests for support {@link TestPropertySource @TestPropertySource} as a + * repeatable annotation. + * + * Test a property definition by the using of {@link TestPropertySource} both in the + * parent class and locally. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestPropertySource(properties = "key = 051187") +public class TestPropertySourceInheritTests extends ParentClassWithTestProperties { + + @Autowired + Environment env; + + @Value("${key}") + String key; + + @Value("${inherited}") + String inherited; + + + @Test + public void inlinePropertyFromParentClassAndFromLocalTestPropertySourceAnnotation() { + assertThat(env.getProperty("key")).isEqualTo("051187"); + assertThat(this.key).isEqualTo("051187"); + + assertThat(env.getProperty("inherited")).isEqualTo("12345"); + assertThat(inherited).isEqualTo("12345"); + } + + + @Configuration + static class Config { + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritedFromMetaAnnotationOverridesLocallyTests.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritedFromMetaAnnotationOverridesLocallyTests.java new file mode 100644 index 000000000000..6787bd8ad909 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritedFromMetaAnnotationOverridesLocallyTests.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + + +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.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for support {@link TestPropertySource @TestPropertySource} as a + * repeatable annotation. + * + * This test verifies an overriding of the property value which declared in the + * meta-annotation by the {@link TestPropertySource} when this property is also defined + * locally in {@link TestPropertySource}. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestPropertySource(properties = "meta = local value") +@AnnotationWithTestProperty +public class TestPropertySourceInheritedFromMetaAnnotationOverridesLocallyTests { + + @Autowired + Environment env; + + @Value("${meta}") + String meta; + + + @Test + public void inlineLocalPropertyAndPropertyFromMetaAnnotation() { + assertThat(env.getProperty("meta")).isEqualTo("local value"); + assertThat(meta).isEqualTo("local value"); + } + + + @Configuration + static class Config { + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritedFromMetaAnnotationTests.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritedFromMetaAnnotationTests.java new file mode 100644 index 000000000000..69bbd72af56a --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritedFromMetaAnnotationTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + + +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.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for support {@link TestPropertySource @TestPropertySource} as a + * repeatable annotation. + * + * This test verifies a declaration of properties by the {@link TestPropertySource} both + * locally and in the custom meta-annotation. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestPropertySource(properties = "key = 051187") +@AnnotationWithTestProperty +public class TestPropertySourceInheritedFromMetaAnnotationTests { + + @Autowired + Environment env; + + @Value("${key}") + String key; + + @Value("${meta}") + String meta; + + + @Test + public void inlineLocalPropertyAndPropertyFromMetaAnnotation() { + // local inlined: + assertThat(env.getProperty("key")).isEqualTo("051187"); + assertThat(this.key).isEqualTo("051187"); + // inlined from meta-annotation: + assertThat(env.getProperty("meta")).isEqualTo("value from meta-annotation"); + assertThat(meta).isEqualTo("value from meta-annotation"); + } + + + @Configuration + static class Config { + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritedFromMetaAnnotationWithPropertiesFileTests.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritedFromMetaAnnotationWithPropertiesFileTests.java new file mode 100644 index 000000000000..7954d92cb482 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceInheritedFromMetaAnnotationWithPropertiesFileTests.java @@ -0,0 +1,76 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + + +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.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for support {@link TestPropertySource @TestPropertySource} as a + * repeatable annotation. + * + * Verify a property value defined both in the properties file which declared in the + * custom annotation {@link AnnotationWithTestPropertyInPropertiesFile} and a definition + * of property by the local usage of {@link TestPropertySource} with a properties file + * name. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestPropertySource("local.properties") +@AnnotationWithTestPropertyInPropertiesFile +public class TestPropertySourceInheritedFromMetaAnnotationWithPropertiesFileTests { + + @Autowired + Environment env; + + @Value("${key}") + String key; + + @Value("${meta}") + String meta; + + + @Test + public void inlinePropertyFromParentClassAndFromLocalTestPropertySourceAnnotation() { + assertPropertyValue("key", key, "local value"); + assertPropertyValue("meta", meta, "a value from file in the meta-annotation"); + } + + private void assertPropertyValue(String name, String value, String expectedValue) { + assertThat(env.getProperty(name)).isEqualTo(expectedValue); + assertThat(value).isEqualTo(expectedValue); + } + + + @Configuration + static class Config { + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceOverridesInheritedPropertyTests.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceOverridesInheritedPropertyTests.java new file mode 100644 index 000000000000..6d77ed737c5e --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceOverridesInheritedPropertyTests.java @@ -0,0 +1,64 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + +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.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for support {@link TestPropertySource @TestPropertySource} as a + * repeatable annotation. + * + * Verify the overriding of property which defined both in the parent class and locally in + * the {@link TestPropertySource} annotation. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestPropertySource(properties = "inherited = local value") +public class TestPropertySourceOverridesInheritedPropertyTests extends ParentClassWithTestProperties { + + @Autowired + Environment env; + + @Value("${inherited}") + String inherited; + + + @Test + public void inlinePropertyFromParentClassAndFromLocalTestPropertySourceAnnotation() { + assertThat(env.getProperty("inherited")).isEqualTo("local value"); + assertThat(inherited).isEqualTo("local value"); + } + + + @Configuration + static class Config { + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourcePartialOverridesInheritedPropertyTests.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourcePartialOverridesInheritedPropertyTests.java new file mode 100644 index 000000000000..f59aa073f886 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourcePartialOverridesInheritedPropertyTests.java @@ -0,0 +1,63 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + +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.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for support {@link TestPropertySource @TestPropertySource} as a + * repeatable annotation. + * + * Verify the overriding of property which defined both in the parent class and locally in + * the {@link TestPropertySource} annotation. Also, verify that the value of not + * conflicted properties is applied from the parent class. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestPropertySource(properties = "second = local value") +public class TestPropertySourcePartialOverridesInheritedPropertyTests extends ParentClassWithMultipleTestProperties { + + @Value("${first}") + String first; + + @Value("${second}") + String second; + + + @Test + public void inlinePropertyFromParentClassAndFromLocalTestPropertySourceAnnotation() { + assertThat(first).isEqualTo("value from parent class"); + assertThat(second).isEqualTo("local value"); + } + + + @Configuration + static class Config { + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableOverridesTests.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableOverridesTests.java new file mode 100644 index 000000000000..268238518103 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableOverridesTests.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + +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.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for support {@link TestPropertySource @TestPropertySource} as a + * repeatable annotation. + * + * Verify an overriding of a property value which defined both in custom annotation + * and in the parent class, when this property declares locally by the + * {@link TestPropertySource}. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@FooTestProperty +@TestPropertySource(properties = "foo = local value") +public class TestPropertySourceRepeatableOverridesTests extends FooTestPropertyDeclaration { + + @Value("${foo}") + String foo; + + @Test + public void inlinePropertyFromParentClassAndFromLocalTestPropertySourceAnnotation() { + assertThat(foo).isEqualTo("local value"); + } + + @Configuration + static class Config { + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableTests.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableTests.java new file mode 100644 index 000000000000..0e9b5f4165d1 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + +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.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for support {@link TestPropertySource @TestPropertySource} as a + * repeatable annotation. + * + * Test multiple test property declarations by the using of {@link TestPropertySource} as + * a repeatable annotation. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestPropertySource(properties = "first = 1111") +@TestPropertySource(properties = "second = 2222") +public class TestPropertySourceRepeatableTests { + + @Autowired + Environment env; + + @Value("${first}") + String first; + + @Value("${second}") + String second; + + + @Test + public void inlinePropertyFromParentClassAndFromLocalTestPropertySourceAnnotation() { + assertPropertyValue("first", first, "1111"); + assertPropertyValue("second", second, "2222"); + } + + private void assertPropertyValue(String name, String value, String expectedValue) { + assertThat(env.getProperty(name)).isEqualTo(expectedValue); + assertThat(value).isEqualTo(expectedValue); + } + + + @Configuration + static class Config { + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableWithDefaultPropertiesFileTests.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableWithDefaultPropertiesFileTests.java new file mode 100644 index 000000000000..cac36f6b3fcd --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableWithDefaultPropertiesFileTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + +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.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for support {@link TestPropertySource @TestPropertySource} as a + * repeatable annotation. + * + * Verify a repeatable usage of {@link TestPropertySource} both with a default value of + * properties file and with a specified properties file name in the + * {@link TestPropertySource} annotation. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestPropertySource +@TestPropertySource("local.properties") +public class TestPropertySourceRepeatableWithDefaultPropertiesFileTests { + + @Autowired + Environment env; + + @Value("${key}") + String key; + + @Value("${default.value}") + String defaultValue; + + @Test + public void inlinePropertyFromParentClassAndFromLocalTestPropertySourceAnnotation() { + assertPropertyValue("key", key, "local value"); + assertPropertyValue("default.value", defaultValue, "a value from default properties file"); + } + + private void assertPropertyValue(String name, String value, String expectedValue) { + assertThat(env.getProperty(name)).isEqualTo(expectedValue); + assertThat(value).isEqualTo(expectedValue); + } + + + @Configuration + static class Config { + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableWithPropertiesFileTests.java b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableWithPropertiesFileTests.java new file mode 100644 index 000000000000..c3932af07eb7 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableWithPropertiesFileTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2002-2019 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 + * + * https://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.test.context.env.repeatable; + +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.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for support {@link TestPropertySource @TestPropertySource} as a + * repeatable annotation. + * + * Test multiple test properties file declarations by the using of {@link TestPropertySource} as + * a repeatable annotation. + * + * @author Anatoliy Korovin + * @since 5.2 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@TestPropertySource("first.properties") +@TestPropertySource("second.properties") +public class TestPropertySourceRepeatableWithPropertiesFileTests { + + @Autowired + Environment env; + + @Value("${first}") + String first; + + @Value("${second}") + String second; + + + @Test + public void inlinePropertyFromParentClassAndFromLocalTestPropertySourceAnnotation() { + assertPropertyValue("first", first, "1111"); + assertPropertyValue("second", second, "2222"); + } + + private void assertPropertyValue(String name, String value, String expectedValue) { + assertThat(env.getProperty(name)).isEqualTo(expectedValue); + assertThat(value).isEqualTo(expectedValue); + } + + + @Configuration + static class Config { + } +} diff --git a/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableWithDefaultPropertiesFileTests.properties b/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableWithDefaultPropertiesFileTests.properties new file mode 100644 index 000000000000..ca6ec5bbb483 --- /dev/null +++ b/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/TestPropertySourceRepeatableWithDefaultPropertiesFileTests.properties @@ -0,0 +1 @@ +default.value = a value from default properties file \ No newline at end of file diff --git a/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/first.properties b/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/first.properties new file mode 100644 index 000000000000..2330dfc6148d --- /dev/null +++ b/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/first.properties @@ -0,0 +1 @@ +first = 1111 \ No newline at end of file diff --git a/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/local.properties b/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/local.properties new file mode 100644 index 000000000000..7bbf2a52d931 --- /dev/null +++ b/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/local.properties @@ -0,0 +1 @@ +key = local value \ No newline at end of file diff --git a/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/meta.properties b/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/meta.properties new file mode 100644 index 000000000000..ca8c37957726 --- /dev/null +++ b/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/meta.properties @@ -0,0 +1 @@ +meta = a value from file in the meta-annotation \ No newline at end of file diff --git a/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/second.properties b/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/second.properties new file mode 100644 index 000000000000..722f3912aac6 --- /dev/null +++ b/spring-test/src/test/resources/org/springframework/test/context/env/repeatable/second.properties @@ -0,0 +1 @@ +second = 2222 \ No newline at end of file