Assert context uniqueness against merged config
Prior to this commit, the uniqueness check for @ContextConfiguration
attributes within a @ContextHierarchy was performed at a single test
class level instead of against the merged configuration for all test
class levels in the test class hierarchy.
This commit addresses this issue by moving the uniqueness check
algorithm from resolveContextHierarchyAttributes() to
buildContextHierarchyMap() within ContextLoaderUtils.
Issue: SPR-11011
Backport-Commit: 7658d856ca
This commit is contained in:
parent
5d8aa635c6
commit
63de2fab4c
|
|
@ -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
|
||||
* <em>present</em> on the supplied class; if a given class in the class hierarchy
|
||||
* <em>present</em> 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<ContextConfigurationAttributes> configAttributesSet = new HashSet<ContextConfigurationAttributes>(
|
||||
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<List<ContextConfigurationAttributes>> set = new HashSet<List<ContextConfigurationAttributes>>(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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<String, List<ContextConfigurationAttributes>> 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<String, List<ContextConfigurationAttributes>> map = buildContextHierarchyMap(TestClass2WithMultiLevelContextHierarchyWithOverriddenInitializers.class);
|
||||
|
||||
assertThat(map.size(), is(2));
|
||||
assertThat(map.keySet(), hasItems("alpha", "beta"));
|
||||
|
||||
List<ContextConfigurationAttributes> 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<ContextConfigurationAttributes> 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<ConfigurableApplicationContext> {
|
||||
|
||||
@Override
|
||||
public void initialize(ConfigurableApplicationContext applicationContext) {
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue