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
This commit is contained in:
Sam Brannen
2014-02-22 02:03:06 +01:00
parent 76cc6db5fc
commit 78b69f5d77
16 changed files with 402 additions and 68 deletions

View File

@@ -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
* <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.
* <em>present</em> 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);
}