Finalize API for TestContextAnnotationUtils

This commit is contained in:
Sam Brannen
2020-10-27 00:18:01 +01:00
parent 82fa3f3fc1
commit fc9650a9a6
8 changed files with 191 additions and 271 deletions

View File

@@ -0,0 +1,133 @@
/*
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.context;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.junit.jupiter.api.Test;
import org.springframework.core.annotation.AliasFor;
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.TestContextAnnotationUtils.findAnnotationDescriptor;
/**
* Unit tests for {@link TestContextAnnotationUtils} that verify support for
* overridden meta-annotation attributes.
*
* <p>See <a href="https://jira.spring.io/browse/SPR-10181">SPR-10181</a>.
*
* @author Sam Brannen
* @since 5.3, though originally since 4.0 for the deprecated
* {@link org.springframework.test.util.MetaAnnotationUtils} support
* @see TestContextAnnotationUtilsTests
*/
class OverriddenMetaAnnotationAttributesTestContextAnnotationUtilsTests {
@Test
void contextConfigurationValue() {
Class<?> rootDeclaringClass = MetaValueConfigTestCase.class;
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(rootDeclaringClass,
ContextConfiguration.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(rootDeclaringClass);
assertThat(descriptor.getDeclaringClass()).isEqualTo(MetaValueConfig.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
assertThat(descriptor.getAnnotation().value()).containsExactly("foo.xml");
assertThat(descriptor.getAnnotation().locations()).containsExactly("foo.xml");
}
@Test
void overriddenContextConfigurationValue() {
Class<?> rootDeclaringClass = OverriddenMetaValueConfigTestCase.class;
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(rootDeclaringClass,
ContextConfiguration.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(rootDeclaringClass);
assertThat(descriptor.getDeclaringClass()).isEqualTo(MetaValueConfig.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
assertThat(descriptor.getAnnotation().value()).containsExactly("bar.xml");
assertThat(descriptor.getAnnotation().locations()).containsExactly("bar.xml");
}
@Test
void contextConfigurationLocationsAndInheritLocations() {
Class<?> rootDeclaringClass = MetaLocationsConfigTestCase.class;
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(rootDeclaringClass,
ContextConfiguration.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(rootDeclaringClass);
assertThat(descriptor.getDeclaringClass()).isEqualTo(MetaLocationsConfig.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
assertThat(descriptor.getAnnotation().value()).isEmpty();
assertThat(descriptor.getAnnotation().locations()).isEmpty();
assertThat(descriptor.getAnnotation().inheritLocations()).isTrue();
}
@Test
void overriddenContextConfigurationLocationsAndInheritLocations() {
Class<?> rootDeclaringClass = OverriddenMetaLocationsConfigTestCase.class;
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(rootDeclaringClass,
ContextConfiguration.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(rootDeclaringClass);
assertThat(descriptor.getDeclaringClass()).isEqualTo(MetaLocationsConfig.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
assertThat(descriptor.getAnnotation().value()).containsExactly("bar.xml");
assertThat(descriptor.getAnnotation().locations()).containsExactly("bar.xml");
assertThat(descriptor.getAnnotation().inheritLocations()).isTrue();
}
// -------------------------------------------------------------------------
@ContextConfiguration
@Retention(RetentionPolicy.RUNTIME)
@interface MetaValueConfig {
@AliasFor(annotation = ContextConfiguration.class)
String[] value() default "foo.xml";
}
@MetaValueConfig
static class MetaValueConfigTestCase {
}
@MetaValueConfig("bar.xml")
static class OverriddenMetaValueConfigTestCase {
}
@ContextConfiguration(locations = "foo.xml", inheritLocations = false)
@Retention(RetentionPolicy.RUNTIME)
@interface MetaLocationsConfig {
String[] locations() default {};
boolean inheritLocations();
}
@MetaLocationsConfig(inheritLocations = true)
static class MetaLocationsConfigTestCase {
}
@MetaLocationsConfig(locations = "bar.xml", inheritLocations = true)
static class OverriddenMetaLocationsConfigTestCase {
}
}

View File

@@ -1,156 +0,0 @@
/*
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.context;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.junit.jupiter.api.Test;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.context.TestContextAnnotationUtils.findAnnotationDescriptor;
/**
* Unit tests for {@link TestContextAnnotationUtils} that verify support for
* overridden meta-annotation attributes.
*
* <p>See <a href="https://jira.spring.io/browse/SPR-10181">SPR-10181</a>.
*
* @author Sam Brannen
* @since 4.0
* @see TestContextAnnotationUtilsTests
*/
class OverriddenMetaAnnotationAttributesTests {
@Test
void contextConfigurationValue() throws Exception {
Class<MetaValueConfigTestCase> declaringClass = MetaValueConfigTestCase.class;
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
ContextConfiguration.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
assertThat(descriptor.getComposedAnnotation()).isNotNull();
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
// direct access to annotation value:
assertThat(descriptor.getAnnotation().value()).isEqualTo(new String[] { "foo.xml" });
}
@Test
void overriddenContextConfigurationValue() throws Exception {
Class<?> declaringClass = OverriddenMetaValueConfigTestCase.class;
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
ContextConfiguration.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
assertThat(descriptor.getComposedAnnotation()).isNotNull();
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
// direct access to annotation value:
assertThat(descriptor.getAnnotation().value()).isEqualTo(new String[] { "foo.xml" });
// overridden attribute:
AnnotationAttributes attributes = descriptor.getAnnotationAttributes();
// NOTE: we would like to be able to override the 'value' attribute; however,
// Spring currently does not allow overrides for the 'value' attribute.
// See SPR-11393 for related discussions.
assertThat(attributes.getStringArray("value")).isEqualTo(new String[] { "foo.xml" });
}
@Test
void contextConfigurationLocationsAndInheritLocations() throws Exception {
Class<MetaLocationsConfigTestCase> declaringClass = MetaLocationsConfigTestCase.class;
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
ContextConfiguration.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
assertThat(descriptor.getComposedAnnotation()).isNotNull();
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
// direct access to annotation attributes:
assertThat(descriptor.getAnnotation().locations()).isEqualTo(new String[] { "foo.xml" });
assertThat(descriptor.getAnnotation().inheritLocations()).isFalse();
}
@Test
void overriddenContextConfigurationLocationsAndInheritLocations() throws Exception {
Class<?> declaringClass = OverriddenMetaLocationsConfigTestCase.class;
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
ContextConfiguration.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
assertThat(descriptor.getComposedAnnotation()).isNotNull();
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
// direct access to annotation attributes:
assertThat(descriptor.getAnnotation().locations()).isEqualTo(new String[] { "foo.xml" });
assertThat(descriptor.getAnnotation().inheritLocations()).isFalse();
// overridden attributes:
AnnotationAttributes attributes = descriptor.getAnnotationAttributes();
assertThat(attributes.getStringArray("locations")).isEqualTo(new String[] { "bar.xml" });
assertThat(attributes.getBoolean("inheritLocations")).isTrue();
}
// -------------------------------------------------------------------------
@ContextConfiguration("foo.xml")
@Retention(RetentionPolicy.RUNTIME)
static @interface MetaValueConfig {
String[] value() default {};
}
@MetaValueConfig
static class MetaValueConfigTestCase {
}
@MetaValueConfig("bar.xml")
static class OverriddenMetaValueConfigTestCase {
}
@ContextConfiguration(locations = "foo.xml", inheritLocations = false)
@Retention(RetentionPolicy.RUNTIME)
static @interface MetaLocationsConfig {
String[] locations() default {};
boolean inheritLocations();
}
@MetaLocationsConfig(inheritLocations = true)
static class MetaLocationsConfigTestCase {
}
@MetaLocationsConfig(locations = "bar.xml", inheritLocations = true)
static class OverriddenMetaLocationsConfigTestCase {
}
}

View File

@@ -47,8 +47,9 @@ import static org.springframework.test.context.TestContextAnnotationUtils.search
* Unit tests for {@link TestContextAnnotationUtils}.
*
* @author Sam Brannen
* @since 4.0
* @see OverriddenMetaAnnotationAttributesTests
* @since 5.3, though originally since 4.0 for the deprecated
* {@link org.springframework.test.util.MetaAnnotationUtils} support
* @see OverriddenMetaAnnotationAttributesTestContextAnnotationUtilsTests
*/
class TestContextAnnotationUtilsTests {
@@ -167,8 +168,6 @@ class TestContextAnnotationUtilsTests {
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(HasLocalAndMetaComponentAnnotation.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
assertThat(descriptor.getComposedAnnotation()).isNull();
assertThat(descriptor.getComposedAnnotationType()).isNull();
}
@Test
@@ -186,7 +185,6 @@ class TestContextAnnotationUtilsTests {
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(ClassWithMetaAnnotatedInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(Meta1.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
assertThat(descriptor.getComposedAnnotation().annotationType()).isEqualTo(Meta1.class);
}
@Test
@@ -198,10 +196,8 @@ class TestContextAnnotationUtilsTests {
assertThat(descriptor.getRootDeclaringClass()).as("rootDeclaringClass").isEqualTo(MetaAnnotatedAndSuperAnnotatedContextConfigClass.class);
assertThat(descriptor.getDeclaringClass()).as("declaringClass").isEqualTo(MetaConfig.class);
assertThat(descriptor.getAnnotationType()).as("annotationType").isEqualTo(ContextConfiguration.class);
assertThat(descriptor.getComposedAnnotation()).as("composedAnnotation should not be null").isNotNull();
assertThat(descriptor.getComposedAnnotationType()).as("composedAnnotationType").isEqualTo(MetaConfig.class);
assertThat(descriptor.getAnnotationAttributes().getClassArray("classes")).as("configured classes").isEqualTo(new Class<?>[] {String.class});
assertThat(descriptor.getAnnotation().classes()).as("configured classes").containsExactly(String.class);
}
@Test
@@ -220,8 +216,8 @@ class TestContextAnnotationUtilsTests {
*/
@Test
void findAnnotationDescriptorOnMetaMetaAnnotatedClass() {
Class<MetaMetaAnnotatedClass> startClass = MetaMetaAnnotatedClass.class;
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2", MetaMeta.class);
Class<?> startClass = MetaMetaAnnotatedClass.class;
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2");
}
/**
@@ -229,8 +225,8 @@ class TestContextAnnotationUtilsTests {
*/
@Test
void findAnnotationDescriptorOnMetaMetaMetaAnnotatedClass() {
Class<MetaMetaMetaAnnotatedClass> startClass = MetaMetaMetaAnnotatedClass.class;
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2", MetaMetaMeta.class);
Class<?> startClass = MetaMetaMetaAnnotatedClass.class;
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2");
}
/**
@@ -263,11 +259,11 @@ class TestContextAnnotationUtilsTests {
private void assertAtComponentOnComposedAnnotation(
Class<?> startClass, Class<?> rootDeclaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
assertAtComponentOnComposedAnnotation(startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType);
assertAtComponentOnComposedAnnotation(startClass, rootDeclaringClass, composedAnnotationType, name);
}
private void assertAtComponentOnComposedAnnotation(Class<?> startClass, Class<?> rootDeclaringClass,
Class<?> declaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
Class<?> declaringClass, String name) {
AnnotationDescriptor<Component> descriptor = findAnnotationDescriptor(startClass, Component.class);
assertThat(descriptor).as("AnnotationDescriptor should not be null").isNotNull();
@@ -275,8 +271,6 @@ class TestContextAnnotationUtilsTests {
assertThat(descriptor.getDeclaringClass()).as("declaringClass").isEqualTo(declaringClass);
assertThat(descriptor.getAnnotationType()).as("annotationType").isEqualTo(Component.class);
assertThat(descriptor.getAnnotation().value()).as("component name").isEqualTo(name);
assertThat(descriptor.getComposedAnnotation()).as("composedAnnotation should not be null").isNotNull();
assertThat(descriptor.getComposedAnnotationType()).as("composedAnnotationType").isEqualTo(composedAnnotationType);
}
}
@@ -362,13 +356,11 @@ class TestContextAnnotationUtilsTests {
HasLocalAndMetaComponentAnnotation.class, Transactional.class, annotationType, Order.class);
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(HasLocalAndMetaComponentAnnotation.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
assertThat(descriptor.getComposedAnnotation()).isNull();
assertThat(descriptor.getComposedAnnotationType()).isNull();
}
@Test
void findAnnotationDescriptorForTypesWithMetaComponentAnnotation() {
Class<HasMetaComponentAnnotation> startClass = HasMetaComponentAnnotation.class;
Class<?> startClass = HasMetaComponentAnnotation.class;
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta1", Meta1.class);
}
@@ -384,10 +376,9 @@ class TestContextAnnotationUtilsTests {
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(startClass);
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
assertThat(((ContextConfiguration) descriptor.getAnnotation()).value()).isEqualTo(new Class<?>[] {});
assertThat(descriptor.getAnnotationAttributes().getClassArray("classes")).isEqualTo(new Class<?>[] {MetaConfig.DevConfig.class, MetaConfig.ProductionConfig.class});
assertThat(descriptor.getComposedAnnotation()).isNotNull();
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaConfig.class);
assertThat(((ContextConfiguration) descriptor.getAnnotation()).value()).isEmpty();
assertThat(((ContextConfiguration) descriptor.getAnnotation()).classes())
.containsExactly(MetaConfig.DevConfig.class, MetaConfig.ProductionConfig.class);
}
@Test
@@ -402,15 +393,14 @@ class TestContextAnnotationUtilsTests {
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(startClass);
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
assertThat(((ContextConfiguration) descriptor.getAnnotation()).value()).isEqualTo(new Class<?>[] {});
assertThat(descriptor.getAnnotationAttributes().getClassArray("classes")).isEqualTo(new Class<?>[] {TestContextAnnotationUtilsTests.class});
assertThat(descriptor.getComposedAnnotation()).isNotNull();
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaConfig.class);
assertThat(((ContextConfiguration) descriptor.getAnnotation()).value()).isEmpty();
assertThat(((ContextConfiguration) descriptor.getAnnotation()).classes())
.containsExactly(TestContextAnnotationUtilsTests.class);
}
@Test
void findAnnotationDescriptorForTypesForInterfaceWithMetaAnnotation() {
Class<InterfaceWithMetaAnnotation> startClass = InterfaceWithMetaAnnotation.class;
Class<?> startClass = InterfaceWithMetaAnnotation.class;
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta1", Meta1.class);
}
@@ -426,12 +416,11 @@ class TestContextAnnotationUtilsTests {
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(ClassWithMetaAnnotatedInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(Meta1.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
assertThat(descriptor.getComposedAnnotation().annotationType()).isEqualTo(Meta1.class);
}
@Test
void findAnnotationDescriptorForTypesForClassWithLocalMetaAnnotationAndMetaAnnotatedInterface() {
Class<ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface> startClass = ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class;
Class<?> startClass = ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class;
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta2", Meta2.class);
}
@@ -447,9 +436,9 @@ class TestContextAnnotationUtilsTests {
*/
@Test
void findAnnotationDescriptorForTypesOnMetaMetaAnnotatedClass() {
Class<MetaMetaAnnotatedClass> startClass = MetaMetaAnnotatedClass.class;
Class<?> startClass = MetaMetaAnnotatedClass.class;
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
startClass, startClass, Meta2.class, "meta2", MetaMeta.class);
startClass, startClass, Meta2.class, "meta2");
}
/**
@@ -457,9 +446,9 @@ class TestContextAnnotationUtilsTests {
*/
@Test
void findAnnotationDescriptorForTypesOnMetaMetaMetaAnnotatedClass() {
Class<MetaMetaMetaAnnotatedClass> startClass = MetaMetaMetaAnnotatedClass.class;
Class<?> startClass = MetaMetaMetaAnnotatedClass.class;
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
startClass, startClass, Meta2.class, "meta2", MetaMetaMeta.class);
startClass, startClass, Meta2.class, "meta2");
}
/**
@@ -497,13 +486,12 @@ class TestContextAnnotationUtilsTests {
Class<?> rootDeclaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType);
startClass, rootDeclaringClass, composedAnnotationType, name);
}
@SuppressWarnings("unchecked")
private void assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(Class<?> startClass,
Class<?> rootDeclaringClass, Class<?> declaringClass, String name,
Class<? extends Annotation> composedAnnotationType) {
Class<?> rootDeclaringClass, Class<?> declaringClass, String name) {
Class<Component> annotationType = Component.class;
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
@@ -514,8 +502,6 @@ class TestContextAnnotationUtilsTests {
assertThat(descriptor.getDeclaringClass()).as("declaringClass").isEqualTo(declaringClass);
assertThat(descriptor.getAnnotationType()).as("annotationType").isEqualTo(annotationType);
assertThat(((Component) descriptor.getAnnotation()).value()).as("component name").isEqualTo(name);
assertThat(descriptor.getComposedAnnotation()).as("composedAnnotation should not be null").isNotNull();
assertThat(descriptor.getComposedAnnotationType()).as("composedAnnotationType").isEqualTo(composedAnnotationType);
}
}