diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoaderUtils.java b/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoaderUtils.java
index 51dfbaac63a..83a1d365e1a 100644
--- a/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoaderUtils.java
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoaderUtils.java
@@ -32,7 +32,7 @@ import org.springframework.util.StringUtils;
/**
* Utility methods for working with {@link ContextLoader ContextLoaders}.
*
- *
TODO: Consider refactoring into a stateful ContextLoaderResolver.
+ *
TODO Consider refactoring into a stateful ContextLoaderResolver.
*
* @author Sam Brannen
* @since 3.1
@@ -44,6 +44,9 @@ public abstract class ContextLoaderUtils {
private static final String STANDARD_DEFAULT_CONTEXT_LOADER_CLASS_NAME = "org.springframework.test.context.support.GenericXmlContextLoader";
+ private static final ClassNameLocationsResolver classNameLocationsResolver = new ClassNameLocationsResolver();
+ private static final ResourcePathLocationsResolver resourcePathLocationsResolver = new ResourcePathLocationsResolver();
+
/**
* TODO Document resolveContextLoader().
@@ -164,53 +167,29 @@ public abstract class ContextLoaderUtils {
Class annotationType = ContextConfiguration.class;
Class> declaringClass = AnnotationUtils.findAnnotationDeclaringClass(annotationType, clazz);
- Assert.notNull(declaringClass, "Could not find an 'annotation declaring class' for annotation type ["
- + annotationType + "] and class [" + clazz + "]");
+ Assert.notNull(declaringClass, String.format(
+ "Could not find an 'annotation declaring class' for annotation type [%s] and class [%s]", annotationType,
+ clazz));
boolean processConfigurationClasses = (contextLoader instanceof ResourceTypeAwareContextLoader)
&& ((ResourceTypeAwareContextLoader) contextLoader).supportsClassResources();
-
- return processConfigurationClasses ? //
- resolveConfigurationClassNames(contextLoader, annotationType, declaringClass)
- : resolveStringLocations(contextLoader, annotationType, declaringClass);
- }
-
- /**
- * TODO Document resolveStringLocations().
- *
- * @param contextLoader
- * @param annotationType
- * @param declaringClass
- * @return
- */
- private static String[] resolveStringLocations(ContextLoader contextLoader,
- Class annotationType, Class> declaringClass) {
+ LocationsResolver locationsResolver = processConfigurationClasses ? classNameLocationsResolver
+ : resourcePathLocationsResolver;
List locationsList = new ArrayList();
while (declaringClass != null) {
ContextConfiguration contextConfiguration = declaringClass.getAnnotation(annotationType);
+
if (logger.isTraceEnabled()) {
logger.trace(String.format("Retrieved @ContextConfiguration [%s] for declaring class [%s].",
contextConfiguration, declaringClass));
}
- String[] valueLocations = contextConfiguration.value();
- String[] locations = contextConfiguration.locations();
- if (!ObjectUtils.isEmpty(valueLocations) && !ObjectUtils.isEmpty(locations)) {
- String msg = String.format(
- "Test class [%s] has been configured with @ContextConfiguration's 'value' [%s] and 'locations' [%s] attributes. Only one declaration of resource locations is permitted per @ContextConfiguration annotation.",
- declaringClass, ObjectUtils.nullSafeToString(valueLocations),
- ObjectUtils.nullSafeToString(locations));
- logger.error(msg);
- throw new IllegalStateException(msg);
- }
- else if (!ObjectUtils.isEmpty(valueLocations)) {
- locations = valueLocations;
- }
+ String[] resolvedLocations = locationsResolver.resolveLocations(contextConfiguration, declaringClass);
+ String[] processedLocations = contextLoader.processLocations(declaringClass, resolvedLocations);
+ locationsList.addAll(0, Arrays. asList(processedLocations));
- locations = contextLoader.processLocations(declaringClass, locations);
- locationsList.addAll(0, Arrays. asList(locations));
declaringClass = contextConfiguration.inheritLocations() ? AnnotationUtils.findAnnotationDeclaringClass(
annotationType, declaringClass.getSuperclass()) : null;
}
@@ -218,37 +197,52 @@ public abstract class ContextLoaderUtils {
return locationsList.toArray(new String[locationsList.size()]);
}
- /**
- * TODO Document resolveConfigClassNames().
- *
- * @param contextLoader
- * @param annotationType
- * @param declaringClass
- * @return
- */
- private static String[] resolveConfigurationClassNames(ContextLoader contextLoader,
- Class annotationType, Class> declaringClass) {
- // TODO [SPR-6184] Implement recursive search for configuration classes.
+ private static interface LocationsResolver {
- ContextConfiguration contextConfiguration = declaringClass.getAnnotation(annotationType);
- if (logger.isTraceEnabled()) {
- logger.trace(String.format("Retrieved @ContextConfiguration [%s] for declaring class [%s].",
- contextConfiguration, declaringClass));
- }
+ String[] resolveLocations(ContextConfiguration contextConfiguration, Class> declaringClass);
+ }
- String[] classNames = null;
+ private static final class ResourcePathLocationsResolver implements LocationsResolver {
- Class>[] configClasses = contextConfiguration.classes();
- if (!ObjectUtils.isEmpty(configClasses)) {
- classNames = new String[configClasses.length];
+ public String[] resolveLocations(ContextConfiguration contextConfiguration, Class> declaringClass) {
- for (int i = 0; i < configClasses.length; i++) {
- classNames[i] = configClasses[i].getName();
+ String[] locations = contextConfiguration.locations();
+ String[] valueLocations = contextConfiguration.value();
+
+ if (!ObjectUtils.isEmpty(valueLocations) && !ObjectUtils.isEmpty(locations)) {
+ String msg = String.format(
+ "Test class [%s] has been configured with @ContextConfiguration's 'value' [%s] and 'locations' [%s] attributes. Only one declaration of resource locations is permitted per @ContextConfiguration annotation.",
+ declaringClass, ObjectUtils.nullSafeToString(valueLocations),
+ ObjectUtils.nullSafeToString(locations));
+ ContextLoaderUtils.logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ else if (!ObjectUtils.isEmpty(valueLocations)) {
+ locations = valueLocations;
}
- }
- return contextLoader.processLocations(declaringClass, classNames);
+ return locations;
+ }
+ }
+
+ private static final class ClassNameLocationsResolver implements LocationsResolver {
+
+ public String[] resolveLocations(ContextConfiguration contextConfiguration, Class> declaringClass) {
+
+ String[] classNames = null;
+
+ Class>[] configClasses = contextConfiguration.classes();
+ if (!ObjectUtils.isEmpty(configClasses)) {
+ classNames = new String[configClasses.length];
+
+ for (int i = 0; i < configClasses.length; i++) {
+ classNames[i] = configClasses[i].getName();
+ }
+ }
+
+ return classNames;
+ }
}
}
diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4SuiteTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4SuiteTests.java
index 069eb427174..58bff255cd3 100644
--- a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4SuiteTests.java
+++ b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4SuiteTests.java
@@ -22,6 +22,8 @@ import org.junit.runners.Suite.SuiteClasses;
import org.springframework.test.context.ClassLevelDirtiesContextTests;
import org.springframework.test.context.SpringRunnerContextCacheTests;
import org.springframework.test.context.junit4.annotation.AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests;
+import org.springframework.test.context.junit4.annotation.DefaultConfigClassBaseTests;
+import org.springframework.test.context.junit4.annotation.DefaultConfigClassInheritedTests;
import org.springframework.test.context.junit4.orm.HibernateSessionFlushingTests;
/**
@@ -50,6 +52,8 @@ StandardJUnit4FeaturesTests.class,//
StandardJUnit4FeaturesSpringRunnerTests.class,//
SpringJUnit47ClassRunnerRuleTests.class,//
AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.class,//
+ DefaultConfigClassBaseTests.class,//
+ DefaultConfigClassInheritedTests.class,//
ExpectedExceptionSpringRunnerTests.class,//
TimedSpringRunnerTests.class,//
RepeatedSpringRunnerTests.class,//
diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.java
index 91df99f1393..4b2b7eb0673 100644
--- a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.java
+++ b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.java
@@ -26,7 +26,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader;
* @author Sam Brannen
* @since 3.1
*/
-@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = PojoAndStringConfig.class)
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = PojoAndStringConfig.class, inheritLocations = false)
public class AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests extends SpringJUnit4ClassRunnerAppCtxTests {
/* all tests are in the parent class. */
}
diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSuiteTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSuiteTests.java
index 740c7888e11..7c5445634b6 100644
--- a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSuiteTests.java
+++ b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSuiteTests.java
@@ -28,14 +28,10 @@ import org.junit.runners.Suite.SuiteClasses;
*/
@RunWith(Suite.class)
// Note: the following 'multi-line' layout is for enhanced code readability.
-@SuiteClasses({
-
-AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.class,
-
-DefaultConfigClassBaseTests.class,
-
-DefaultConfigClassInheritedTests.class
-
+@SuiteClasses({//
+AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.class,//
+ DefaultConfigClassBaseTests.class,//
+ DefaultConfigClassInheritedTests.class //
})
public class AnnotationConfigSuiteTests {
}
diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultConfigClassInheritedTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultConfigClassInheritedTests.java
index caf769b49b9..0c0011a5bfd 100644
--- a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultConfigClassInheritedTests.java
+++ b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/DefaultConfigClassInheritedTests.java
@@ -19,7 +19,6 @@ package org.springframework.test.context.junit4.annotation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.Pet;
import org.springframework.beans.factory.annotation.Autowired;
@@ -31,7 +30,6 @@ import org.springframework.test.context.ContextConfiguration;
* @author Sam Brannen
* @since 3.1
*/
-@Ignore("[SPR-6184] Disabled until ContextLoaderUtils supports recursive search for configuration classes")
@ContextConfiguration
public class DefaultConfigClassInheritedTests extends DefaultConfigClassBaseTests {