From 78b69f5d77792d86b62997f4fb5c9258ed93a186 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 22 Feb 2014 02:03:06 +0100 Subject: [PATCH] Always supply test class to ContextLoaders in TCF Prior to this commit, the following methods in ContextLoaderUtils treated a composed @ContextConfiguration annotation (i.e., a custom annotation that is meta-annotated with @ContextConfiguration) as the "declaring class" instead of the actual test class. - resolveContextConfigurationAttributes() - resolveContextHierarchyAttributes() As a consequence, if @ContextConfiguration is used as a meta-annotation, the meta-annotated class is stored as the "declaringClass" in ContextConfigurationAttributes. Thus, when a ContextLoader (or SmartContextLoader) attempts to detect default resource locations or configuration classes, it does so for the composed annotation class instead of for the declaring test class. This commit ensures that ContextLoaders are supplied the declaring test class instead of the composed annotation class in such use cases. Issue: SPR-11455 --- .../test/context/ContextLoaderUtils.java | 14 +-- .../AbstractContextLoaderUtilsTests.java | 12 +-- ...aderUtilsConfigurationAttributesTests.java | 39 ++++---- ...ntextLoaderUtilsContextHierarchyTests.java | 19 ++-- ...eResolverWithCustomDefaultsMetaConfig.java | 89 +++++++++++++++++++ ...lverWithCustomDefaultsMetaConfigTests.java | 45 ++++++++++ ...mDefaultsMetaConfigWithOverridesTests.java | 71 +++++++++++++++ .../ConfigClassesAndProfilesMetaConfig.java | 45 ++++++++++ ...nfigClassesAndProfilesMetaConfigTests.java | 70 +++++++++++++++ ...ProfilesWithCustomDefaultsMetaConfig.java} | 7 +- ...lesWithCustomDefaultsMetaConfigTests.java} | 8 +- ...DefaultsMetaConfigWithOverridesTests.java} | 9 +- .../annotation/meta/MetaMetaConfig.java | 9 +- .../meta/MetaMetaConfigDefaultsTests.java | 6 +- .../web/MetaAnnotationConfigWacTests.java | 9 +- ...reotype.java => WebTestConfiguration.java} | 18 ++-- 16 files changed, 402 insertions(+), 68 deletions(-) create mode 100644 spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java create mode 100644 spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests.java create mode 100644 spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigWithOverridesTests.java create mode 100644 spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfig.java create mode 100644 spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfigTests.java rename spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/{MetaConfig.java => ConfigClassesAndProfilesWithCustomDefaultsMetaConfig.java} (89%) rename spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/{MetaConfigDefaultsTests.java => ConfigClassesAndProfilesWithCustomDefaultsMetaConfigTests.java} (79%) rename spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/{MetaConfigOverrideTests.java => ConfigClassesAndProfilesWithCustomDefaultsMetaConfigWithOverridesTests.java} (79%) rename spring-test/src/test/java/org/springframework/test/context/web/{WebTestStereotype.java => WebTestConfiguration.java} (80%) diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextLoaderUtils.java b/spring-test/src/main/java/org/springframework/test/context/ContextLoaderUtils.java index 51a1b3dcc89..a3bd700d35d 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextLoaderUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextLoaderUtils.java @@ -261,9 +261,9 @@ abstract class ContextLoaderUtils { * never {@code null} * @throws IllegalArgumentException if the supplied class is {@code null}; if * neither {@code @ContextConfiguration} nor {@code @ContextHierarchy} is - * present on the supplied class; or if a given class in the class hierarchy - * declares both {@code @ContextConfiguration} and {@code @ContextHierarchy} as - * top-level annotations. + * present on the supplied class; or if a test class or composed annotation + * in the class hierarchy declares both {@code @ContextConfiguration} and + * {@code @ContextHierarchy} as top-level annotations. * @throws IllegalStateException if no class in the class hierarchy declares * {@code @ContextHierarchy}. * @@ -296,7 +296,7 @@ abstract class ContextLoaderUtils { if (contextConfigDeclaredLocally && contextHierarchyDeclaredLocally) { String msg = String.format("Class [%s] has been configured with both @ContextConfiguration " + "and @ContextHierarchy. Only one of these annotations may be declared on a test class " - + "or custom stereotype annotation.", declaringClass.getName()); + + "or composed annotation.", declaringClass.getName()); logger.error(msg); throw new IllegalStateException(msg); } @@ -305,12 +305,12 @@ abstract class ContextLoaderUtils { if (contextConfigDeclaredLocally) { convertAnnotationAttributesToConfigAttributesAndAddToList(descriptor.getAnnotationAttributes(), - declaringClass, configAttributesList); + rootDeclaringClass, configAttributesList); } else if (contextHierarchyDeclaredLocally) { ContextHierarchy contextHierarchy = getAnnotation(declaringClass, contextHierarchyType); for (ContextConfiguration contextConfiguration : contextHierarchy.value()) { - convertContextConfigToConfigAttributesAndAddToList(contextConfiguration, declaringClass, + convertContextConfigToConfigAttributesAndAddToList(contextConfiguration, rootDeclaringClass, configAttributesList); } } @@ -428,7 +428,7 @@ abstract class ContextLoaderUtils { while (descriptor != null) { convertAnnotationAttributesToConfigAttributesAndAddToList(descriptor.getAnnotationAttributes(), - descriptor.getDeclaringClass(), attributesList); + descriptor.getRootDeclaringClass(), attributesList); descriptor = findAnnotationDescriptor(descriptor.getRootDeclaringClass().getSuperclass(), annotationType); } diff --git a/spring-test/src/test/java/org/springframework/test/context/AbstractContextLoaderUtilsTests.java b/spring-test/src/test/java/org/springframework/test/context/AbstractContextLoaderUtilsTests.java index bec2fa7e300..06515d42695 100644 --- a/spring-test/src/test/java/org/springframework/test/context/AbstractContextLoaderUtilsTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/AbstractContextLoaderUtilsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -47,11 +47,11 @@ abstract class AbstractContextLoaderUtilsTests { void assertAttributes(ContextConfigurationAttributes attributes, Class expectedDeclaringClass, String[] expectedLocations, Class[] expectedClasses, Class expectedContextLoaderClass, boolean expectedInheritLocations) { - assertEquals(expectedDeclaringClass, attributes.getDeclaringClass()); - assertArrayEquals(expectedLocations, attributes.getLocations()); - assertArrayEquals(expectedClasses, attributes.getClasses()); - assertEquals(expectedInheritLocations, attributes.isInheritLocations()); - assertEquals(expectedContextLoaderClass, attributes.getContextLoaderClass()); + assertEquals("declaring class", expectedDeclaringClass, attributes.getDeclaringClass()); + assertArrayEquals("locations", expectedLocations, attributes.getLocations()); + assertArrayEquals("classes", expectedClasses, attributes.getClasses()); + assertEquals("inherit locations", expectedInheritLocations, attributes.isInheritLocations()); + assertEquals("context loader", expectedContextLoaderClass, attributes.getContextLoaderClass()); } void assertMergedConfig(MergedContextConfiguration mergedConfig, Class expectedTestClass, diff --git a/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsConfigurationAttributesTests.java b/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsConfigurationAttributesTests.java index d41708a120b..f32d068e431 100644 --- a/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsConfigurationAttributesTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsConfigurationAttributesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -59,11 +59,12 @@ public class ContextLoaderUtilsConfigurationAttributesTests extends AbstractCont @Test public void resolveConfigAttributesWithBareAnnotations() { - List attributesList = resolveContextConfigurationAttributes(BareAnnotations.class); + Class testClass = BareAnnotations.class; + List attributesList = resolveContextConfigurationAttributes(testClass); assertNotNull(attributesList); assertEquals(1, attributesList.size()); - assertAttributes(attributesList.get(0), BareAnnotations.class, EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, - ContextLoader.class, true); + assertAttributes(attributesList.get(0), testClass, EMPTY_STRING_ARRAY, EMPTY_CLASS_ARRAY, ContextLoader.class, + true); } @Test @@ -76,39 +77,43 @@ public class ContextLoaderUtilsConfigurationAttributesTests extends AbstractCont @Test public void resolveConfigAttributesWithMetaAnnotationAndLocations() { - List attributesList = resolveContextConfigurationAttributes(MetaLocationsFoo.class); + Class testClass = MetaLocationsFoo.class; + List attributesList = resolveContextConfigurationAttributes(testClass); assertNotNull(attributesList); assertEquals(1, attributesList.size()); - assertAttributes(attributesList.get(0), MetaLocationsFooConfig.class, new String[] { "/foo.xml" }, - EMPTY_CLASS_ARRAY, ContextLoader.class, true); + assertAttributes(attributesList.get(0), testClass, new String[] { "/foo.xml" }, EMPTY_CLASS_ARRAY, + ContextLoader.class, true); } @Test public void resolveConfigAttributesWithMetaAnnotationAndLocationsAndOverrides() { - List attributesList = resolveContextConfigurationAttributes(MetaLocationsFooWithOverrides.class); + Class testClass = MetaLocationsFooWithOverrides.class; + List attributesList = resolveContextConfigurationAttributes(testClass); assertNotNull(attributesList); assertEquals(1, attributesList.size()); - assertAttributes(attributesList.get(0), MetaLocationsFooConfigWithOverrides.class, new String[] { "/foo.xml" }, - EMPTY_CLASS_ARRAY, ContextLoader.class, true); + assertAttributes(attributesList.get(0), testClass, new String[] { "/foo.xml" }, EMPTY_CLASS_ARRAY, + ContextLoader.class, true); } @Test public void resolveConfigAttributesWithMetaAnnotationAndLocationsAndOverriddenAttributes() { - List attributesList = resolveContextConfigurationAttributes(MetaLocationsFooWithOverriddenAttributes.class); + Class testClass = MetaLocationsFooWithOverriddenAttributes.class; + List attributesList = resolveContextConfigurationAttributes(testClass); assertNotNull(attributesList); assertEquals(1, attributesList.size()); - assertAttributes(attributesList.get(0), MetaLocationsFooConfigWithOverrides.class, new String[] { "foo1.xml", - "foo2.xml" }, EMPTY_CLASS_ARRAY, ContextLoader.class, true); + assertAttributes(attributesList.get(0), testClass, new String[] { "foo1.xml", "foo2.xml" }, EMPTY_CLASS_ARRAY, + ContextLoader.class, true); } @Test public void resolveConfigAttributesWithMetaAnnotationAndLocationsInClassHierarchy() { - List attributesList = resolveContextConfigurationAttributes(MetaLocationsBar.class); + Class testClass = MetaLocationsBar.class; + List attributesList = resolveContextConfigurationAttributes(testClass); assertNotNull(attributesList); assertEquals(2, attributesList.size()); - assertAttributes(attributesList.get(0), MetaLocationsBarConfig.class, new String[] { "/bar.xml" }, - EMPTY_CLASS_ARRAY, ContextLoader.class, true); - assertAttributes(attributesList.get(1), MetaLocationsFooConfig.class, new String[] { "/foo.xml" }, + assertAttributes(attributesList.get(0), testClass, new String[] { "/bar.xml" }, EMPTY_CLASS_ARRAY, + ContextLoader.class, true); + assertAttributes(attributesList.get(1), MetaLocationsFoo.class, new String[] { "/foo.xml" }, EMPTY_CLASS_ARRAY, ContextLoader.class, true); } diff --git a/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsContextHierarchyTests.java b/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsContextHierarchyTests.java index 2a0b24820cb..11c82054d6a 100644 --- a/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsContextHierarchyTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsContextHierarchyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -71,15 +71,16 @@ public class ContextLoaderUtilsContextHierarchyTests extends AbstractContextLoad @Test public void resolveContextHierarchyAttributesForSingleTestClassWithSingleLevelContextHierarchyFromMetaAnnotation() { - List> hierarchyAttributes = resolveContextHierarchyAttributes(SingleTestClassWithSingleLevelContextHierarchyFromMetaAnnotation.class); + Class testClass = SingleTestClassWithSingleLevelContextHierarchyFromMetaAnnotation.class; + List> hierarchyAttributes = resolveContextHierarchyAttributes(testClass); assertEquals(1, hierarchyAttributes.size()); List configAttributesList = hierarchyAttributes.get(0); assertNotNull(configAttributesList); assertEquals(1, configAttributesList.size()); debugConfigAttributes(configAttributesList); - assertAttributes(configAttributesList.get(0), ContextHierarchyA.class, new String[] { "A.xml" }, - EMPTY_CLASS_ARRAY, ContextLoader.class, true); + assertAttributes(configAttributesList.get(0), testClass, new String[] { "A.xml" }, EMPTY_CLASS_ARRAY, + ContextLoader.class, true); } @Test @@ -131,7 +132,8 @@ public class ContextLoaderUtilsContextHierarchyTests extends AbstractContextLoad debugConfigAttributes(configAttributesListClassLevel1); assertEquals(1, configAttributesListClassLevel1.size()); assertThat(configAttributesListClassLevel1.get(0).getLocations()[0], equalTo("A.xml")); - assertAttributes(configAttributesListClassLevel1.get(0), ContextHierarchyA.class, new String[] { "A.xml" }, + assertAttributes(configAttributesListClassLevel1.get(0), + TestClass1WithSingleLevelContextHierarchyFromMetaAnnotation.class, new String[] { "A.xml" }, EMPTY_CLASS_ARRAY, ContextLoader.class, true); List configAttributesListClassLevel2 = hierarchyAttributes.get(1); @@ -139,14 +141,17 @@ public class ContextLoaderUtilsContextHierarchyTests extends AbstractContextLoad assertEquals(1, configAttributesListClassLevel2.size()); assertArrayEquals(new String[] { "B-one.xml", "B-two.xml" }, configAttributesListClassLevel2.get(0).getLocations()); - assertAttributes(configAttributesListClassLevel2.get(0), ContextHierarchyB.class, new String[] { "B-one.xml", + assertAttributes(configAttributesListClassLevel2.get(0), + TestClass2WithSingleLevelContextHierarchyFromMetaAnnotation.class, + new String[] { "B-one.xml", "B-two.xml" }, EMPTY_CLASS_ARRAY, ContextLoader.class, true); List configAttributesListClassLevel3 = hierarchyAttributes.get(2); debugConfigAttributes(configAttributesListClassLevel3); assertEquals(1, configAttributesListClassLevel3.size()); assertThat(configAttributesListClassLevel3.get(0).getLocations()[0], equalTo("C.xml")); - assertAttributes(configAttributesListClassLevel3.get(0), ContextHierarchyC.class, new String[] { "C.xml" }, + assertAttributes(configAttributesListClassLevel3.get(0), + TestClass3WithSingleLevelContextHierarchyFromMetaAnnotation.class, new String[] { "C.xml" }, EMPTY_CLASS_ARRAY, ContextLoader.class, true); } diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java new file mode 100644 index 00000000000..d23a7b2c40e --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig.java @@ -0,0 +1,89 @@ +/* + * Copyright 2002-2014 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.test.context.junit4.annotation.meta; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ActiveProfilesResolver; +import org.springframework.test.context.ContextConfiguration; + +/** + * Custom configuration annotation with meta-annotation attribute overrides for + * {@link ContextConfiguration#classes} and {@link ActiveProfiles#resolver} and + * with default configuration local to the composed annotation. + * + * @author Sam Brannen + * @since 4.0.3 + */ +@ContextConfiguration +@ActiveProfiles +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig { + + @Configuration + @Profile("dev") + static class DevConfig { + + @Bean + public String foo() { + return "Dev Foo"; + } + } + + @Configuration + @Profile("prod") + static class ProductionConfig { + + @Bean + public String foo() { + return "Production Foo"; + } + } + + @Configuration + @Profile("resolver") + static class ResolverConfig { + + @Bean + public String foo() { + return "Resolver Foo"; + } + } + + static class CustomResolver implements ActiveProfilesResolver { + + @Override + public String[] resolve(Class testClass) { + return testClass.getSimpleName().equals("ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests") ? new String[] { "resolver" } + : new String[] {}; + } + } + + + Class[] classes() default { DevConfig.class, ProductionConfig.class, ResolverConfig.class }; + + Class resolver() default CustomResolver.class; + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests.java new file mode 100644 index 00000000000..9b713a33bf1 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-2014 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.test.context.junit4.annotation.meta; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.junit.Assert.*; + +/** + * Integration tests for meta-annotation attribute override support, relying on + * default attribute values defined in {@link ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig}. + * + * @author Sam Brannen + * @since 4.0.3 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig +public class ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigTests { + + @Autowired + private String foo; + + + @Test + public void foo() { + assertEquals("Resolver Foo", foo); + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigWithOverridesTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigWithOverridesTests.java new file mode 100644 index 00000000000..fb504dbcf8e --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigWithOverridesTests.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2014 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.test.context.junit4.annotation.meta; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.test.context.ActiveProfilesResolver; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.junit.Assert.*; + +/** + * Integration tests for meta-annotation attribute override support, overriding + * default attribute values defined in {@link ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig}. + * + * @author Sam Brannen + * @since 4.0.3 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfig(classes = LocalDevConfig.class, resolver = DevResolver.class) +public class ConfigClassesAndProfileResolverWithCustomDefaultsMetaConfigWithOverridesTests { + + @Autowired + private String foo; + + + @Test + public void foo() { + assertEquals("Local Dev Foo", foo); + } +} + +@Configuration +@Profile("dev") +class LocalDevConfig { + + @Bean + public String foo() { + return "Local Dev Foo"; + } +} + +class DevResolver implements ActiveProfilesResolver { + + @Override + public String[] resolve(Class testClass) { + // Checking that the "test class" name ends with "*Tests" ensures that an actual + // test class is passed to this method as opposed to a "*Config" class which would + // imply that we likely have been passed the 'declaringClass' instead of the + // 'rootDeclaringClass'. + return testClass.getName().endsWith("Tests") ? new String[] { "dev" } : new String[] {}; + } +} \ No newline at end of file diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfig.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfig.java new file mode 100644 index 00000000000..f5269f8d37c --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfig.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-2014 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.test.context.junit4.annotation.meta; + +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.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; + +/** + * Custom configuration annotation with meta-annotation attribute overrides for + * {@link ContextConfiguration#classes} and {@link ActiveProfiles#profiles} and + * no default configuration local to the composed annotation. + * + * @author Sam Brannen + * @since 4.0.3 + */ +@ContextConfiguration +@ActiveProfiles +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ConfigClassesAndProfilesMetaConfig { + + Class[] classes() default {}; + + String[] profiles() default {}; + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfigTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfigTests.java new file mode 100644 index 00000000000..01386b97f12 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesMetaConfigTests.java @@ -0,0 +1,70 @@ +/* + * Copyright 2002-2014 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.test.context.junit4.annotation.meta; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.junit.Assert.*; + +/** + * Integration tests for meta-annotation attribute override support, demonstrating + * that the test class is used as the declaring class when detecting default + * configuration classes for the declaration of {@code @ContextConfiguration}. + * + * @author Sam Brannen + * @since 4.0.3 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ConfigClassesAndProfilesMetaConfig(profiles = "dev") +public class ConfigClassesAndProfilesMetaConfigTests { + + @Configuration + @Profile("dev") + static class DevConfig { + + @Bean + public String foo() { + return "Local Dev Foo"; + } + } + + @Configuration + @Profile("prod") + static class ProductionConfig { + + @Bean + public String foo() { + return "Local Production Foo"; + } + } + + + @Autowired + private String foo; + + + @Test + public void foo() { + assertEquals("Local Dev Foo", foo); + } +} diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaConfig.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfig.java similarity index 89% rename from spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaConfig.java rename to spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfig.java index 51d2ec70a98..399ddc29f98 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaConfig.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -29,7 +29,8 @@ import org.springframework.test.context.ContextConfiguration; /** * Custom configuration annotation with meta-annotation attribute overrides for - * {@link ContextConfiguration#classes} and {@link ActiveProfiles#profiles}. + * {@link ContextConfiguration#classes} and {@link ActiveProfiles#profiles} and + * with default configuration local to the composed annotation. * * @author Sam Brannen * @since 4.0 @@ -38,7 +39,7 @@ import org.springframework.test.context.ContextConfiguration; @ActiveProfiles @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -public @interface MetaConfig { +public @interface ConfigClassesAndProfilesWithCustomDefaultsMetaConfig { @Configuration @Profile("dev") diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaConfigDefaultsTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigTests.java similarity index 79% rename from spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaConfigDefaultsTests.java rename to spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigTests.java index 0e42192f6e4..55b30ae2da7 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaConfigDefaultsTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -25,14 +25,14 @@ import static org.junit.Assert.*; /** * Integration tests for meta-annotation attribute override support, relying on - * default attribute values defined in {@link MetaConfig @MetaConfig}. + * default attribute values defined in {@link ConfigClassesAndProfilesWithCustomDefaultsMetaConfig}. * * @author Sam Brannen * @since 4.0 */ @RunWith(SpringJUnit4ClassRunner.class) -@MetaConfig -public class MetaConfigDefaultsTests { +@ConfigClassesAndProfilesWithCustomDefaultsMetaConfig +public class ConfigClassesAndProfilesWithCustomDefaultsMetaConfigTests { @Autowired private String foo; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaConfigOverrideTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigWithOverridesTests.java similarity index 79% rename from spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaConfigOverrideTests.java rename to spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigWithOverridesTests.java index 3567d28bdd6..c7e05b30236 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaConfigOverrideTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/ConfigClassesAndProfilesWithCustomDefaultsMetaConfigWithOverridesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -28,14 +28,15 @@ import static org.junit.Assert.*; /** * Integration tests for meta-annotation attribute override support, overriding - * default attribute values defined in {@link MetaConfig}. + * default attribute values defined in {@link ConfigClassesAndProfilesWithCustomDefaultsMetaConfig}. * * @author Sam Brannen * @since 4.0 */ @RunWith(SpringJUnit4ClassRunner.class) -@MetaConfig(classes = { PojoAndStringConfig.class, MetaConfig.ProductionConfig.class }, profiles = "prod") -public class MetaConfigOverrideTests { +@ConfigClassesAndProfilesWithCustomDefaultsMetaConfig(classes = { PojoAndStringConfig.class, + ConfigClassesAndProfilesWithCustomDefaultsMetaConfig.ProductionConfig.class }, profiles = "prod") +public class ConfigClassesAndProfilesWithCustomDefaultsMetaConfigWithOverridesTests { @Autowired private String foo; diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfig.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfig.java index d468addee0c..9cdd6dacf48 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfig.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfig.java @@ -24,16 +24,17 @@ import java.lang.annotation.Target; import org.springframework.test.context.ActiveProfiles; /** - * Custom configuration annotation that is itself meta-annotated with - * {@link MetaConfig @MetaConfig} and {@link ActiveProfiles @ActiveProfiles}. + * Custom configuration annotation that is itself meta-annotated with {@link + * ConfigClassesAndProfilesWithCustomDefaultsMetaConfig} and {@link ActiveProfiles}. * * @author Sam Brannen * @since 4.0.3 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -@MetaConfig -// Override default "dev" profile from @MetaConfig: +@ConfigClassesAndProfilesWithCustomDefaultsMetaConfig +// Override default "dev" profile from +// @ConfigClassesAndProfilesWithCustomDefaultsMetaConfig: @ActiveProfiles("prod") public @interface MetaMetaConfig { diff --git a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfigDefaultsTests.java b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfigDefaultsTests.java index 87277690e0e..6ad89e9f314 100644 --- a/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfigDefaultsTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/junit4/annotation/meta/MetaMetaConfigDefaultsTests.java @@ -24,9 +24,9 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.junit.Assert.*; /** - * Integration tests for meta-meta-annotation support, relying on - * default attribute values defined in {@link MetaConfig @MetaConfig} and - * overrides in {@link MetaMetaConfig @MetaMetaConfig}. + * Integration tests for meta-meta-annotation support, relying on default attribute + * values defined in {@link ConfigClassesAndProfilesWithCustomDefaultsMetaConfig} and + * overrides in {@link MetaMetaConfig}. * * @author Sam Brannen * @since 4.0.3 diff --git a/spring-test/src/test/java/org/springframework/test/context/web/MetaAnnotationConfigWacTests.java b/spring-test/src/test/java/org/springframework/test/context/web/MetaAnnotationConfigWacTests.java index 37d4f6d1c0f..5ca2197929f 100644 --- a/spring-test/src/test/java/org/springframework/test/context/web/MetaAnnotationConfigWacTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/web/MetaAnnotationConfigWacTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -22,6 +22,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockServletContext; +import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.web.context.WebApplicationContext; @@ -29,14 +30,14 @@ import static org.junit.Assert.*; /** * Integration test that verifies meta-annotation support for {@link WebAppConfiguration} - * and {@link org.springframework.test.context.ContextConfiguration ContextConfiguration}. + * and {@link ContextConfiguration}. * * @author Sam Brannen * @since 4.0 - * @see WebTestStereotype + * @see WebTestConfiguration */ @RunWith(SpringJUnit4ClassRunner.class) -@WebTestStereotype +@WebTestConfiguration public class MetaAnnotationConfigWacTests { @Autowired diff --git a/spring-test/src/test/java/org/springframework/test/context/web/WebTestStereotype.java b/spring-test/src/test/java/org/springframework/test/context/web/WebTestConfiguration.java similarity index 80% rename from spring-test/src/test/java/org/springframework/test/context/web/WebTestStereotype.java rename to spring-test/src/test/java/org/springframework/test/context/web/WebTestConfiguration.java index 1ee2c727279..be4f29d3a39 100644 --- a/spring-test/src/test/java/org/springframework/test/context/web/WebTestStereotype.java +++ b/spring-test/src/test/java/org/springframework/test/context/web/WebTestConfiguration.java @@ -24,23 +24,23 @@ import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; /** - * Custom stereotype combining {@link WebAppConfiguration} and + * Custom composed annotation combining {@link WebAppConfiguration} and * {@link ContextConfiguration} as meta-annotations. * * @author Sam Brannen * @since 4.0 */ @WebAppConfiguration -@ContextConfiguration +@ContextConfiguration(classes = FooConfig.class) @Retention(RetentionPolicy.RUNTIME) -public @interface WebTestStereotype { +public @interface WebTestConfiguration { +} - @Configuration - static class Config { +@Configuration +class FooConfig { - @Bean - public String foo() { - return "enigma"; - } + @Bean + public String foo() { + return "enigma"; } } \ No newline at end of file