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 a43897eb0b6..f71e447b6c4 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
@@ -237,11 +237,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; if a given class in the class hierarchy
+ * 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; or if individual {@code @ContextConfiguration}
- * elements within a {@code @ContextHierarchy} declaration on a given class
- * in the class hierarchy do not define unique context configuration.
+ * top-level annotations.
*
* @since 3.2.2
* @see #buildContextHierarchyMap(Class)
@@ -287,17 +285,6 @@ abstract class ContextLoaderUtils {
convertContextConfigToConfigAttributesAndAddToList(contextConfiguration, declaringClass,
configAttributesList);
}
-
- // Check for uniqueness
- Set configAttributesSet = new HashSet(
- configAttributesList);
- if (configAttributesSet.size() != configAttributesList.size()) {
- String msg = String.format("The @ContextConfiguration elements configured via "
- + "@ContextHierarchy in test class [%s] must define unique contexts to load.",
- declaringClass.getName());
- logger.error(msg);
- throw new IllegalStateException(msg);
- }
}
else {
// This should theoretically actually never happen...
@@ -336,6 +323,9 @@ abstract class ContextLoaderUtils {
* (must not be {@code null})
* @return a map of context configuration attributes for the context hierarchy,
* keyed by context hierarchy level name; never {@code null}
+ * @throws IllegalArgumentException if the lists of context configuration
+ * attributes for each level in the {@code @ContextHierarchy} do not define
+ * unique context configuration within the overall hierarchy.
*
* @since 3.2.2
* @see #resolveContextHierarchyAttributes(Class)
@@ -363,6 +353,16 @@ abstract class ContextLoaderUtils {
}
}
+ // Check for uniqueness
+ Set> set = new HashSet>(map.values());
+ if (set.size() != map.size()) {
+ String msg = String.format("The @ContextConfiguration elements configured via "
+ + "@ContextHierarchy in test class [%s] and its superclasses must "
+ + "define unique contexts per hierarchy level.", testClass.getName());
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+
return map;
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsTests.java b/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsTests.java
index ecedda4ddf9..9553efc8343 100644
--- a/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/ContextLoaderUtilsTests.java
@@ -225,29 +225,6 @@ public class ContextLoaderUtilsTests {
assertThat(configAttributesListClassLevel3.get(2).getLocations()[0], equalTo("3-C.xml"));
}
- private void assertContextConfigEntriesAreNotUnique(Class> testClass) {
- try {
- resolveContextHierarchyAttributes(testClass);
- fail("Should throw an IllegalStateException");
- }
- catch (IllegalStateException e) {
- String msg = String.format(
- "The @ContextConfiguration elements configured via @ContextHierarchy in test class [%s] must define unique contexts to load.",
- testClass.getName());
- assertEquals(msg, e.getMessage());
- }
- }
-
- @Test
- public void resolveContextHierarchyAttributesForSingleTestClassWithMultiLevelContextHierarchyWithEmptyContextConfig() {
- assertContextConfigEntriesAreNotUnique(SingleTestClassWithMultiLevelContextHierarchyWithEmptyContextConfig.class);
- }
-
- @Test
- public void resolveContextHierarchyAttributesForSingleTestClassWithMultiLevelContextHierarchyWithDuplicatedContextConfig() {
- assertContextConfigEntriesAreNotUnique(SingleTestClassWithMultiLevelContextHierarchyWithDuplicatedContextConfig.class);
- }
-
@Test
public void buildContextHierarchyMapForTestClassHierarchyWithMultiLevelContextHierarchies() {
Map> map = buildContextHierarchyMap(TestClass3WithMultiLevelContextHierarchy.class);
@@ -335,6 +312,58 @@ public class ContextLoaderUtilsTests {
assertThat(level3Config.get(0).getLocations()[0], is("2-C.xml"));
}
+ private void assertContextConfigEntriesAreNotUnique(Class> testClass) {
+ try {
+ buildContextHierarchyMap(testClass);
+ fail("Should throw an IllegalStateException");
+ }
+ catch (IllegalStateException e) {
+ String msg = String.format(
+ "The @ContextConfiguration elements configured via @ContextHierarchy in test class [%s] and its superclasses must define unique contexts per hierarchy level.",
+ testClass.getName());
+ assertEquals(msg, e.getMessage());
+ }
+ }
+
+ @Test
+ public void buildContextHierarchyMapForSingleTestClassWithMultiLevelContextHierarchyWithEmptyContextConfig() {
+ assertContextConfigEntriesAreNotUnique(SingleTestClassWithMultiLevelContextHierarchyWithEmptyContextConfig.class);
+ }
+
+ @Test
+ public void buildContextHierarchyMapForSingleTestClassWithMultiLevelContextHierarchyWithDuplicatedContextConfig() {
+ assertContextConfigEntriesAreNotUnique(SingleTestClassWithMultiLevelContextHierarchyWithDuplicatedContextConfig.class);
+ }
+
+ /**
+ * Used to reproduce bug reported in https://jira.springsource.org/browse/SPR-10997
+ */
+ @Test
+ public void buildContextHierarchyMapForTestClassHierarchyWithMultiLevelContextHierarchiesAndOverriddenInitializers() {
+ Map> map = buildContextHierarchyMap(TestClass2WithMultiLevelContextHierarchyWithOverriddenInitializers.class);
+
+ assertThat(map.size(), is(2));
+ assertThat(map.keySet(), hasItems("alpha", "beta"));
+
+ List alphaConfig = map.get("alpha");
+ assertThat(alphaConfig.size(), is(2));
+ assertThat(alphaConfig.get(0).getLocations().length, is(1));
+ assertThat(alphaConfig.get(0).getLocations()[0], is("1-A.xml"));
+ assertThat(alphaConfig.get(0).getInitializers().length, is(0));
+ assertThat(alphaConfig.get(1).getLocations().length, is(0));
+ assertThat(alphaConfig.get(1).getInitializers().length, is(1));
+ assertEquals(DummyApplicationContextInitializer.class, alphaConfig.get(1).getInitializers()[0]);
+
+ List betaConfig = map.get("beta");
+ assertThat(betaConfig.size(), is(2));
+ assertThat(betaConfig.get(0).getLocations().length, is(1));
+ assertThat(betaConfig.get(0).getLocations()[0], is("1-B.xml"));
+ assertThat(betaConfig.get(0).getInitializers().length, is(0));
+ assertThat(betaConfig.get(1).getLocations().length, is(0));
+ assertThat(betaConfig.get(1).getInitializers().length, is(1));
+ assertEquals(DummyApplicationContextInitializer.class, betaConfig.get(1).getInitializers()[0]);
+ }
+
@Test(expected = IllegalStateException.class)
public void resolveConfigAttributesWithConflictingLocations() {
resolveContextConfigurationAttributes(ConflictingLocations.class);
@@ -843,4 +872,40 @@ public class ContextLoaderUtilsTests {
private static class SingleTestClassWithMultiLevelContextHierarchyWithDuplicatedContextConfig {
}
+ /**
+ * Used to reproduce bug reported in https://jira.springsource.org/browse/SPR-10997
+ */
+ @ContextHierarchy({//
+ //
+ @ContextConfiguration(name = "alpha", locations = "1-A.xml"),//
+ @ContextConfiguration(name = "beta", locations = "1-B.xml") //
+ })
+ private static class TestClass1WithMultiLevelContextHierarchyWithUniqueContextConfig {
+ }
+
+ /**
+ * Used to reproduce bug reported in https://jira.springsource.org/browse/SPR-10997
+ */
+ @ContextHierarchy({//
+ //
+ @ContextConfiguration(name = "alpha", initializers = DummyApplicationContextInitializer.class),//
+ @ContextConfiguration(name = "beta", initializers = DummyApplicationContextInitializer.class) //
+ })
+ private static class TestClass2WithMultiLevelContextHierarchyWithOverriddenInitializers extends
+ TestClass1WithMultiLevelContextHierarchyWithUniqueContextConfig {
+ }
+
+ /**
+ * Used to reproduce bug reported in https://jira.springsource.org/browse/SPR-10997
+ */
+ private static class DummyApplicationContextInitializer implements
+ ApplicationContextInitializer {
+
+ @Override
+ public void initialize(ConfigurableApplicationContext applicationContext) {
+ /* no-op */
+ }
+
+ }
+
}