Always pass test class to ActiveProfilesResolver

Prior to this commit, if @ActiveProfiles were used as a meta-annotation
on a composed annotation, then the composed annotation's class would be
passed to the ActiveProfilesResolver.resolve() method instead of the
test class, which breaks the contract for ActiveProfilesResolver.

This commit addresses this issue by ensuring that the actual test class
is always passed to ActiveProfilesResolver.resolve().

Issue: SPR-11467
This commit is contained in:
Sam Brannen 2014-02-22 17:15:11 +01:00
parent 34e90ba7f7
commit 5f7d1758f8
2 changed files with 35 additions and 3 deletions

View File

@ -507,6 +507,7 @@ abstract class ContextLoaderUtils {
final Set<String> activeProfiles = new HashSet<String>();
while (descriptor != null) {
Class<?> rootDeclaringClass = descriptor.getRootDeclaringClass();
Class<?> declaringClass = descriptor.getDeclaringClass();
AnnotationAttributes annAttrs = descriptor.getAnnotationAttributes();
@ -530,12 +531,12 @@ abstract class ContextLoaderUtils {
}
catch (Exception e) {
String msg = String.format("Could not instantiate ActiveProfilesResolver of "
+ "type [%s] for test class [%s].", resolverClass.getName(), declaringClass.getName());
+ "type [%s] for test class [%s].", resolverClass.getName(), rootDeclaringClass.getName());
logger.error(msg);
throw new IllegalStateException(msg, e);
}
profiles = resolver.resolve(declaringClass);
profiles = resolver.resolve(rootDeclaringClass);
if (profiles == null) {
String msg = String.format(
"ActiveProfilesResolver [%s] returned a null array of bean definition profiles.",
@ -555,7 +556,7 @@ abstract class ContextLoaderUtils {
}
descriptor = annAttrs.getBoolean("inheritProfiles") ? findAnnotationDescriptor(
descriptor.getRootDeclaringClass().getSuperclass(), annotationType) : null;
rootDeclaringClass.getSuperclass(), annotationType) : null;
}
return StringUtils.toStringArray(activeProfiles);

View File

@ -205,6 +205,18 @@ public class ContextLoaderUtilsActiveProfilesTests extends AbstractContextLoader
resolveActiveProfiles(NullActiveProfilesResolverTestCase.class);
}
/**
* This test verifies that the actual test class, not the composed annotation,
* is passed to the resolver.
*
* @since 4.0.3
*/
@Test
public void resolveActiveProfilesWithMetaAnnotationAndTestClassVerifyingResolver() {
Class<TestClassVerifyingActiveProfilesResolverTestCase> testClass = TestClassVerifyingActiveProfilesResolverTestCase.class;
assertResolvedProfiles(testClass, testClass.getSimpleName());
}
// -------------------------------------------------------------------------
@ -239,6 +251,12 @@ public class ContextLoaderUtilsActiveProfilesTests extends AbstractContextLoader
boolean inheritProfiles() default false;
}
@ActiveProfiles(resolver = TestClassVerifyingActiveProfilesResolver.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
private static @interface MetaResolverConfig {
}
@MetaAnimalsConfig
private static class MetaAnimals extends MetaLocationsBar {
}
@ -282,6 +300,10 @@ public class ContextLoaderUtilsActiveProfilesTests extends AbstractContextLoader
private static class ConflictingResolverAndValueTestCase {
}
@MetaResolverConfig
private static class TestClassVerifyingActiveProfilesResolverTestCase {
}
@ActiveProfiles(profiles = "conflict", value = "conflict")
private static class ConflictingProfilesAndValueTestCase {
}
@ -322,4 +344,13 @@ public class ContextLoaderUtilsActiveProfilesTests extends AbstractContextLoader
}
}
private static class TestClassVerifyingActiveProfilesResolver implements ActiveProfilesResolver {
@Override
public String[] resolve(Class<?> testClass) {
return testClass.isAnnotation() ? new String[] { "@" + testClass.getSimpleName() }
: new String[] { testClass.getSimpleName() };
}
}
}