From d2d528dc05aa14802af3246e294919b1186c532a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 5 Apr 2016 09:42:41 +0200 Subject: [PATCH] Polishing --- .../test/context/BootstrapUtils.java | 64 ++++++------- .../test/context/TestExecutionListener.java | 10 +-- .../test/context/TestExecutionListeners.java | 86 +++++++++--------- .../test/context/TestPropertySource.java | 30 ++----- .../AbstractTestContextBootstrapper.java | 76 ++++++++-------- .../test/util/MetaAnnotationUtils.java | 21 +++-- .../context/TestExecutionListenersTests.java | 90 +++++++++---------- 7 files changed, 172 insertions(+), 205 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/context/BootstrapUtils.java b/spring-test/src/main/java/org/springframework/test/context/BootstrapUtils.java index db791c35630..79235448c58 100644 --- a/spring-test/src/main/java/org/springframework/test/context/BootstrapUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/BootstrapUtils.java @@ -43,51 +43,47 @@ import static org.springframework.beans.BeanUtils.instantiateClass; */ abstract class BootstrapUtils { - private static final String DEFAULT_BOOTSTRAP_CONTEXT_CLASS_NAME = "org.springframework.test.context.support.DefaultBootstrapContext"; + private static final String DEFAULT_BOOTSTRAP_CONTEXT_CLASS_NAME = + "org.springframework.test.context.support.DefaultBootstrapContext"; - private static final String DEFAULT_CACHE_AWARE_CONTEXT_LOADER_DELEGATE_CLASS_NAME = "org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate"; + private static final String DEFAULT_CACHE_AWARE_CONTEXT_LOADER_DELEGATE_CLASS_NAME = + "org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate"; - private static final String DEFAULT_TEST_CONTEXT_BOOTSTRAPPER_CLASS_NAME = "org.springframework.test.context.support.DefaultTestContextBootstrapper"; + private static final String DEFAULT_TEST_CONTEXT_BOOTSTRAPPER_CLASS_NAME = + "org.springframework.test.context.support.DefaultTestContextBootstrapper"; - private static final String DEFAULT_WEB_TEST_CONTEXT_BOOTSTRAPPER_CLASS_NAME = "org.springframework.test.context.web.WebTestContextBootstrapper"; + private static final String DEFAULT_WEB_TEST_CONTEXT_BOOTSTRAPPER_CLASS_NAME = + "org.springframework.test.context.web.WebTestContextBootstrapper"; - private static final String WEB_APP_CONFIGURATION_ANNOTATION_CLASS_NAME = "org.springframework.test.context.web.WebAppConfiguration"; + private static final String WEB_APP_CONFIGURATION_ANNOTATION_CLASS_NAME = + "org.springframework.test.context.web.WebAppConfiguration"; private static final Log logger = LogFactory.getLog(BootstrapUtils.class); - private BootstrapUtils() { - /* no-op */ - } - /** * Create the {@code BootstrapContext} for the specified {@linkplain Class test class}. - * *

Uses reflection to create a {@link org.springframework.test.context.support.DefaultBootstrapContext} * that uses a {@link org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate}. - * * @param testClass the test class for which the bootstrap context should be created * @return a new {@code BootstrapContext}; never {@code null} */ @SuppressWarnings("unchecked") static BootstrapContext createBootstrapContext(Class testClass) { CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = createCacheAwareContextLoaderDelegate(); - Class clazz = null; try { - clazz = (Class) ClassUtils.forName(DEFAULT_BOOTSTRAP_CONTEXT_CLASS_NAME, - BootstrapUtils.class.getClassLoader()); - - Constructor constructor = clazz.getConstructor(Class.class, - CacheAwareContextLoaderDelegate.class); - + clazz = (Class) ClassUtils.forName( + DEFAULT_BOOTSTRAP_CONTEXT_CLASS_NAME, BootstrapUtils.class.getClassLoader()); + Constructor constructor = clazz.getConstructor( + Class.class, CacheAwareContextLoaderDelegate.class); if (logger.isDebugEnabled()) { logger.debug(String.format("Instantiating BootstrapContext using constructor [%s]", constructor)); } return instantiateClass(constructor, testClass, cacheAwareContextLoaderDelegate); } - catch (Throwable t) { - throw new IllegalStateException("Could not load BootstrapContext [" + clazz + "]", t); + catch (Throwable ex) { + throw new IllegalStateException("Could not load BootstrapContext [" + clazz + "]", ex); } } @@ -104,8 +100,8 @@ abstract class BootstrapUtils { } return instantiateClass(clazz, CacheAwareContextLoaderDelegate.class); } - catch (Throwable t) { - throw new IllegalStateException("Could not load CacheAwareContextLoaderDelegate [" + clazz + "]", t); + catch (Throwable ex) { + throw new IllegalStateException("Could not load CacheAwareContextLoaderDelegate [" + clazz + "]", ex); } } @@ -113,7 +109,6 @@ abstract class BootstrapUtils { * Resolve the {@link TestContextBootstrapper} type for the test class in the * supplied {@link BootstrapContext}, instantiate it, and provide it a reference * to the {@link BootstrapContext}. - * *

If the {@link BootstrapWith @BootstrapWith} annotation is present on * the test class, either directly or as a meta-annotation, then its * {@link BootstrapWith#value value} will be used as the bootstrapper type. @@ -123,7 +118,6 @@ abstract class BootstrapUtils { * {@link org.springframework.test.context.web.WebTestContextBootstrapper * WebTestContextBootstrapper} will be used, depending on the presence of * {@link org.springframework.test.context.web.WebAppConfiguration @WebAppConfiguration}. - * * @param bootstrapContext the bootstrap context to use * @return a fully configured {@code TestContextBootstrapper} */ @@ -138,21 +132,19 @@ abstract class BootstrapUtils { } if (logger.isDebugEnabled()) { logger.debug(String.format("Instantiating TestContextBootstrapper for test class [%s] from class [%s]", - testClass.getName(), clazz.getName())); + testClass.getName(), clazz.getName())); } - TestContextBootstrapper testContextBootstrapper = instantiateClass(clazz, TestContextBootstrapper.class); testContextBootstrapper.setBootstrapContext(bootstrapContext); - return testContextBootstrapper; } catch (Throwable ex) { if (ex instanceof IllegalStateException) { throw (IllegalStateException) ex; } - throw new IllegalStateException("Could not load TestContextBootstrapper [" + clazz - + "]. Specify @BootstrapWith's 'value' attribute " - + "or make the default bootstrapper class available.", ex); + throw new IllegalStateException("Could not load TestContextBootstrapper [" + clazz + + "]. Specify @BootstrapWith's 'value' attribute or make the default bootstrapper class available.", + ex); } } @@ -160,14 +152,16 @@ abstract class BootstrapUtils { * @since 4.3 */ private static Class resolveExplicitTestContextBootstrapper(Class testClass) { - MultiValueMap attributesMultiMap = AnnotatedElementUtils.getAllAnnotationAttributes( - testClass, BootstrapWith.class.getName()); - List values = (attributesMultiMap == null ? null : attributesMultiMap.get(AnnotationUtils.VALUE)); + MultiValueMap attributesMultiMap = + AnnotatedElementUtils.getAllAnnotationAttributes(testClass, BootstrapWith.class.getName()); + List values = (attributesMultiMap != null ? attributesMultiMap.get(AnnotationUtils.VALUE) : null); if (values == null) { return null; } - Assert.state(values.size() == 1, String.format("Configuration error: found multiple declarations of " - + "@BootstrapWith on test class [%s] with values %s", testClass.getName(), values)); + if (values.size() != 1) { + throw new IllegalStateException(String.format("Configuration error: found multiple declarations of " + + "@BootstrapWith on test class [%s] with values %s", testClass.getName(), values)); + } return (Class) values.get(0); } diff --git a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java index 07b84172f1e..fbca021a946 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -20,14 +20,17 @@ package org.springframework.test.context; * {@code TestExecutionListener} defines a listener API for reacting to * test execution events published by the {@link TestContextManager} with which * the listener is registered. + * *

Concrete implementations must provide a {@code public} no-args constructor, * so that listeners can be instantiated transparently by tools and configuration * mechanisms. + * *

Implementations may optionally declare the position in which they should * be ordered among the chain of default listeners via the * {@link org.springframework.core.Ordered Ordered} interface or * {@link org.springframework.core.annotation.Order @Order} annotation. See * {@link TestContextBootstrapper#getTestExecutionListeners()} for details. + * *

Spring provides the following out-of-the-box implementations (all of * which implement {@code Ordered}): *

    @@ -58,7 +61,6 @@ public interface TestExecutionListener { * before class lifecycle callbacks. *

    If a given testing framework does not support before class * lifecycle callbacks, this method will not be called for that framework. - * * @param testContext the test context for the test; never {@code null} * @throws Exception allows any exception to propagate */ @@ -69,7 +71,6 @@ public interface TestExecutionListener { * {@link TestContext test context}, for example by injecting dependencies. *

    This method should be called immediately after instantiation of the test * instance but prior to any framework-specific lifecycle callbacks. - * * @param testContext the test context for the test; never {@code null} * @throws Exception allows any exception to propagate */ @@ -82,7 +83,6 @@ public interface TestExecutionListener { * fixtures. *

    This method should be called immediately prior to framework-specific * before lifecycle callbacks. - * * @param testContext the test context in which the test method will be * executed; never {@code null} * @throws Exception allows any exception to propagate @@ -96,7 +96,6 @@ public interface TestExecutionListener { * fixtures. *

    This method should be called immediately after framework-specific * after lifecycle callbacks. - * * @param testContext the test context in which the test method was * executed; never {@code null} * @throws Exception allows any exception to propagate @@ -110,7 +109,6 @@ public interface TestExecutionListener { * after class lifecycle callbacks. *

    If a given testing framework does not support after class * lifecycle callbacks, this method will not be called for that framework. - * * @param testContext the test context for the test; never {@code null} * @throws Exception allows any exception to propagate */ diff --git a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListeners.java b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListeners.java index 478fcbc33cc..d99c48d7aa9 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListeners.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListeners.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -30,8 +30,8 @@ import org.springframework.core.annotation.AliasFor; * which {@link TestExecutionListener TestExecutionListeners} should be * registered with a {@link TestContextManager}. * - *

    Typically, {@code @TestExecutionListeners} will be used in conjunction with - * {@link ContextConfiguration @ContextConfiguration}. + *

    Typically, {@code @TestExecutionListeners} will be used in conjunction + * with {@link ContextConfiguration @ContextConfiguration}. * *

    As of Spring Framework 4.0, this annotation may be used as a * meta-annotation to create custom composed annotations. @@ -48,42 +48,8 @@ import org.springframework.core.annotation.AliasFor; @Target(ElementType.TYPE) public @interface TestExecutionListeners { - /** - * Enumeration of modes that dictate whether or not explicitly - * declared listeners are merged with the default listeners when - * {@code @TestExecutionListeners} is declared on a class that does - * not inherit listeners from a superclass. - * @since 4.1 - */ - static enum MergeMode { - - /** - * Indicates that locally declared listeners should replace the default - * listeners. - */ - REPLACE_DEFAULTS, - - /** - * Indicates that locally declared listeners should be merged with the - * default listeners. - *

    The merging algorithm ensures that duplicates are removed from - * the list and that the resulting set of merged listeners is sorted - * according to the semantics of - * {@link org.springframework.core.annotation.AnnotationAwareOrderComparator - * AnnotationAwareOrderComparator}. If a listener implements - * {@link org.springframework.core.Ordered Ordered} or is annotated - * with {@link org.springframework.core.annotation.Order @Order} it can - * influence the position in which it is merged with the defaults; otherwise, - * locally declared listeners will simply be appended to the list of default - * listeners when merged. - */ - MERGE_WITH_DEFAULTS - } - - /** * Alias for {@link #listeners}. - * *

    This attribute may not be used in conjunction with * {@link #listeners}, but it may be used instead of {@link #listeners}. */ @@ -93,10 +59,8 @@ public @interface TestExecutionListeners { /** * The {@link TestExecutionListener TestExecutionListeners} to register with * the {@link TestContextManager}. - * *

    This attribute may not be used in conjunction with * {@link #value}, but it may be used instead of {@link #value}. - * * @see org.springframework.test.context.web.ServletTestExecutionListener * @see org.springframework.test.context.support.DependencyInjectionTestExecutionListener * @see org.springframework.test.context.support.DirtiesContextTestExecutionListener @@ -109,7 +73,6 @@ public @interface TestExecutionListeners { /** * Whether or not {@link #listeners TestExecutionListeners} from superclasses * should be inherited. - * *

    The default value is {@code true}, which means that an annotated * class will inherit the listeners defined by an annotated * superclass. Specifically, the listeners for an annotated class will be @@ -122,21 +85,19 @@ public @interface TestExecutionListeners { * {@code DependencyInjectionTestExecutionListener}, * {@code DirtiesContextTestExecutionListener}, and * {@code TransactionalTestExecutionListener}, in that order. - * *

     	 * @TestExecutionListeners({
    -	 *    DependencyInjectionTestExecutionListener.class,
    -	 *    DirtiesContextTestExecutionListener.class
    +	 *     DependencyInjectionTestExecutionListener.class,
    +	 *     DirtiesContextTestExecutionListener.class
     	 * })
     	 * public abstract class AbstractBaseTest {
    -	 * 	// ...
    +	 * 	 // ...
     	 * }
     	 *
     	 * @TestExecutionListeners(TransactionalTestExecutionListener.class)
     	 * public class TransactionalTest extends AbstractBaseTest {
    -	 * 	// ...
    +	 * 	 // ...
     	 * }
    - * *

    If {@code inheritListeners} is set to {@code false}, the listeners for * the annotated class will shadow and effectively replace any * listeners defined by a superclass. @@ -158,4 +119,37 @@ public @interface TestExecutionListeners { */ MergeMode mergeMode() default MergeMode.REPLACE_DEFAULTS; + + /** + * Enumeration of modes that dictate whether or not explicitly + * declared listeners are merged with the default listeners when + * {@code @TestExecutionListeners} is declared on a class that does + * not inherit listeners from a superclass. + * @since 4.1 + */ + enum MergeMode { + + /** + * Indicates that locally declared listeners should replace the default + * listeners. + */ + REPLACE_DEFAULTS, + + /** + * Indicates that locally declared listeners should be merged with the + * default listeners. + *

    The merging algorithm ensures that duplicates are removed from + * the list and that the resulting set of merged listeners is sorted + * according to the semantics of + * {@link org.springframework.core.annotation.AnnotationAwareOrderComparator + * AnnotationAwareOrderComparator}. If a listener implements + * {@link org.springframework.core.Ordered Ordered} or is annotated + * with {@link org.springframework.core.annotation.Order @Order} it can + * influence the position in which it is merged with the defaults; otherwise, + * locally declared listeners will simply be appended to the list of default + * listeners when merged. + */ + MERGE_WITH_DEFAULTS + } + } diff --git a/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java b/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java index 3f481029248..ec2528af29a 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestPropertySource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -90,10 +90,8 @@ public @interface TestPropertySource { /** * Alias for {@link #locations}. - * *

    This attribute may not be used in conjunction with * {@link #locations}, but it may be used instead of {@link #locations}. - * * @see #locations */ @AliasFor("locations") @@ -104,12 +102,10 @@ public @interface TestPropertySource { * {@code Environment}'s set of {@code PropertySources}. Each location * will be added to the enclosing {@code Environment} as its own property * source, in the order declared. - * *

    Supported File Formats

    *

    Both traditional and XML-based properties file formats are supported * — for example, {@code "classpath:/com/example/test.properties"} * or {@code "file:/path/to/file.xml"}. - * *

    Path Resource Semantics

    *

    Each path will be interpreted as a Spring * {@link org.springframework.core.io.Resource Resource}. A plain path @@ -128,17 +124,13 @@ public @interface TestPropertySource { * in paths (i.e., ${...}) will be * {@linkplain org.springframework.core.env.Environment#resolveRequiredPlaceholders(String) resolved} * against the {@code Environment}. - * *

    Default Properties File Detection

    *

    See the class-level Javadoc for a discussion on detection of defaults. - * *

    Precedence

    *

    Properties loaded from resource locations have lower precedence than * inlined {@link #properties}. - * *

    This attribute may not be used in conjunction with * {@link #value}, but it may be used instead of {@link #value}. - * * @see #inheritLocations * @see #value * @see #properties @@ -150,18 +142,15 @@ public @interface TestPropertySource { /** * Whether or not test property source {@link #locations} from superclasses * should be inherited. - * *

    The default value is {@code true}, which means that a test class will * inherit property source locations defined by a superclass. * Specifically, the property source locations for a test class will be * appended to the list of property source locations defined by a superclass. * Thus, subclasses have the option of extending the list of test * property source locations. - * *

    If {@code inheritLocations} is set to {@code false}, the property * source locations for the test class will shadow and effectively * replace any property source locations defined by a superclass. - * *

    In the following example, the {@code ApplicationContext} for * {@code BaseTest} will be loaded using only the {@code "base.properties"} * file as a test property source. In contrast, the {@code ApplicationContext} @@ -172,13 +161,13 @@ public @interface TestPropertySource { * @TestPropertySource("base.properties") * @ContextConfiguration * public class BaseTest { - * // ... + * // ... * } * * @TestPropertySource("extended.properties") * @ContextConfiguration * public class ExtendedTest extends BaseTest { - * // ... + * // ... * } * * @@ -193,7 +182,6 @@ public @interface TestPropertySource { * {@code ApplicationContext} is loaded for the test. All key-value pairs * will be added to the enclosing {@code Environment} as a single test * {@code PropertySource} with the highest precedence. - * *

    Supported Syntax

    *

    The supported syntax for key-value pairs is the same as the * syntax defined for entries in a Java @@ -203,14 +191,11 @@ public @interface TestPropertySource { *

  • {@code "key:value"}
  • *
  • {@code "key value"}
  • *
- * *

Precedence

*

Properties declared via this attribute have higher precedence than * properties loaded from resource {@link #locations}. - * *

This attribute may be used in conjunction with {@link #value} * or {@link #locations}. - * * @see #inheritProperties * @see #locations * @see org.springframework.core.env.PropertySource @@ -220,17 +205,14 @@ public @interface TestPropertySource { /** * Whether or not inlined test {@link #properties} from superclasses should * be inherited. - * *

The default value is {@code true}, which means that a test class will * inherit inlined properties defined by a superclass. Specifically, * the inlined properties for a test class will be appended to the list of * inlined properties defined by a superclass. Thus, subclasses have the * option of extending the list of inlined test properties. - * *

If {@code inheritProperties} is set to {@code false}, the inlined * properties for the test class will shadow and effectively * replace any inlined properties defined by a superclass. - * *

In the following example, the {@code ApplicationContext} for * {@code BaseTest} will be loaded using only the inlined {@code key1} * property. In contrast, the {@code ApplicationContext} for @@ -240,16 +222,14 @@ public @interface TestPropertySource { * @TestPropertySource(properties = "key1 = value1") * @ContextConfiguration * public class BaseTest { - * // ... + * // ... * } - * * @TestPropertySource(properties = "key2 = value2") * @ContextConfiguration * public class ExtendedTest extends BaseTest { - * // ... + * // ... * } * - * * @see #properties */ boolean inheritProperties() default true; diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java index 51bbee68da6..c24e40c37de 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java @@ -110,7 +110,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot @Override public TestContext buildTestContext() { return new DefaultTestContext(getBootstrapContext().getTestClass(), buildMergedContextConfiguration(), - getCacheAwareContextLoaderDelegate()); + getCacheAwareContextLoaderDelegate()); } /** @@ -123,14 +123,14 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot List> classesList = new ArrayList>(); boolean usingDefaults = false; - AnnotationDescriptor descriptor = MetaAnnotationUtils.findAnnotationDescriptor(clazz, - annotationType); + AnnotationDescriptor descriptor = + MetaAnnotationUtils.findAnnotationDescriptor(clazz, annotationType); // Use defaults? if (descriptor == null) { if (logger.isDebugEnabled()) { logger.debug(String.format("@TestExecutionListeners is not present for class [%s]: using defaults.", - clazz.getName())); + clazz.getName())); } usingDefaults = true; classesList.addAll(getDefaultTestExecutionListenerClasses()); @@ -142,21 +142,21 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot TestExecutionListeners testExecutionListeners = descriptor.synthesizeAnnotation(); if (logger.isTraceEnabled()) { logger.trace(String.format("Retrieved @TestExecutionListeners [%s] for declaring class [%s].", - testExecutionListeners, declaringClass.getName())); + testExecutionListeners, declaringClass.getName())); } boolean inheritListeners = testExecutionListeners.inheritListeners(); - AnnotationDescriptor superDescriptor = MetaAnnotationUtils.findAnnotationDescriptor( - descriptor.getRootDeclaringClass().getSuperclass(), annotationType); + AnnotationDescriptor superDescriptor = + MetaAnnotationUtils.findAnnotationDescriptor( + descriptor.getRootDeclaringClass().getSuperclass(), annotationType); // If there are no listeners to inherit, we might need to merge the // locally declared listeners with the defaults. - if ((!inheritListeners || superDescriptor == null) - && (testExecutionListeners.mergeMode() == MergeMode.MERGE_WITH_DEFAULTS)) { + if ((!inheritListeners || superDescriptor == null) && + testExecutionListeners.mergeMode() == MergeMode.MERGE_WITH_DEFAULTS) { if (logger.isDebugEnabled()) { - logger.debug(String.format( - "Merging default listeners with listeners configured via @TestExecutionListeners for class [%s].", - descriptor.getRootDeclaringClass().getName())); + logger.debug(String.format("Merging default listeners with listeners configured via " + + "@TestExecutionListeners for class [%s].", descriptor.getRootDeclaringClass().getName())); } usingDefaults = true; classesList.addAll(getDefaultTestExecutionListenerClasses()); @@ -206,10 +206,10 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot } if (ncdfe != null) { if (logger.isInfoEnabled()) { - logger.info(String.format("Could not instantiate TestExecutionListener [%s]. " - + "Specify custom listener classes or make the default listener classes " - + "(and their required dependencies) available. Offending class: [%s]", - listenerClass.getName(), ncdfe.getMessage())); + logger.info(String.format("Could not instantiate TestExecutionListener [%s]. " + + "Specify custom listener classes or make the default listener classes " + + "(and their required dependencies) available. Offending class: [%s]", + listenerClass.getName(), ncdfe.getMessage())); } } } @@ -234,8 +234,8 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot } catch (Throwable ex) { if (logger.isDebugEnabled()) { - logger.debug("Could not load default TestExecutionListener class [" + className - + "]. Specify custom listener classes or make the default listener classes available.", ex); + logger.debug("Could not load default TestExecutionListener class [" + className + + "]. Specify custom listener classes or make the default listener classes available.", ex); } } } @@ -254,12 +254,11 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot * @see SpringFactoriesLoader#loadFactoryNames */ protected List getDefaultTestExecutionListenerClassNames() { - final List classNames = SpringFactoriesLoader.loadFactoryNames(TestExecutionListener.class, - getClass().getClassLoader()); - + List classNames = + SpringFactoriesLoader.loadFactoryNames(TestExecutionListener.class, getClass().getClassLoader()); if (logger.isInfoEnabled()) { logger.info(String.format("Loaded default TestExecutionListener class names from location [%s]: %s", - SpringFactoriesLoader.FACTORIES_RESOURCE_LOCATION, classNames)); + SpringFactoriesLoader.FACTORIES_RESOURCE_LOCATION, classNames)); } return Collections.unmodifiableList(classNames); } @@ -273,13 +272,14 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot Class testClass = getBootstrapContext().getTestClass(); CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = getCacheAwareContextLoaderDelegate(); - if (MetaAnnotationUtils.findAnnotationDescriptorForTypes(testClass, ContextConfiguration.class, - ContextHierarchy.class) == null) { + if (MetaAnnotationUtils.findAnnotationDescriptorForTypes( + testClass, ContextConfiguration.class, ContextHierarchy.class) == null) { return buildDefaultMergedContextConfiguration(testClass, cacheAwareContextLoaderDelegate); } if (AnnotationUtils.findAnnotation(testClass, ContextHierarchy.class) != null) { - Map> hierarchyMap = ContextLoaderUtils.buildContextHierarchyMap(testClass); + Map> hierarchyMap = + ContextLoaderUtils.buildContextHierarchyMap(testClass); MergedContextConfiguration parentConfig = null; MergedContextConfiguration mergedConfig = null; @@ -293,8 +293,8 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot Assert.notEmpty(reversedList, "ContextConfigurationAttributes list must not be empty"); Class declaringClass = reversedList.get(0).getDeclaringClass(); - mergedConfig = buildMergedContextConfiguration(declaringClass, reversedList, parentConfig, - cacheAwareContextLoaderDelegate, true); + mergedConfig = buildMergedContextConfiguration( + declaringClass, reversedList, parentConfig, cacheAwareContextLoaderDelegate, true); parentConfig = mergedConfig; } @@ -303,8 +303,8 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot } else { return buildMergedContextConfiguration(testClass, - ContextLoaderUtils.resolveContextConfigurationAttributes(testClass), null, - cacheAwareContextLoaderDelegate, true); + ContextLoaderUtils.resolveContextConfigurationAttributes(testClass), + null, cacheAwareContextLoaderDelegate, true); } } @@ -390,14 +390,16 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot Set contextCustomizers = getContextCustomizers(testClass, Collections.unmodifiableList(configAttributesList)); - if (requireLocationsClassesOrInitializers && areAllEmpty(locations, classes, initializers, contextCustomizers)) { + if (requireLocationsClassesOrInitializers && + areAllEmpty(locations, classes, initializers, contextCustomizers)) { throw new IllegalStateException(String.format( - "%s was unable to detect defaults, and no ApplicationContextInitializers " - + "or ContextCustomizers were declared for context configuration attributes %s", + "%s was unable to detect defaults, and no ApplicationContextInitializers " + + "or ContextCustomizers were declared for context configuration attributes %s", contextLoader.getClass().getSimpleName(), configAttributesList)); } - MergedTestPropertySources mergedTestPropertySources = TestPropertySourceUtils.buildMergedTestPropertySources(testClass); + MergedTestPropertySources mergedTestPropertySources = + TestPropertySourceUtils.buildMergedTestPropertySources(testClass); MergedContextConfiguration mergedConfig = new MergedContextConfiguration(testClass, StringUtils.toStringArray(locations), ClassUtils.toClassArray(classes), @@ -485,7 +487,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot } if (logger.isTraceEnabled()) { logger.trace(String.format("Using ContextLoader class [%s] for test class [%s]", - contextLoaderClass.getName(), testClass.getName())); + contextLoaderClass.getName(), testClass.getName())); } return BeanUtils.instantiateClass(contextLoaderClass, ContextLoader.class); } @@ -518,14 +520,14 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot for (ContextConfigurationAttributes configAttributes : configAttributesList) { if (logger.isTraceEnabled()) { logger.trace(String.format("Resolving ContextLoader for context configuration attributes %s", - configAttributes)); + configAttributes)); } Class contextLoaderClass = configAttributes.getContextLoaderClass(); if (ContextLoader.class != contextLoaderClass) { if (logger.isDebugEnabled()) { logger.debug(String.format( - "Found explicit ContextLoader class [%s] for context configuration attributes %s", - contextLoaderClass.getName(), configAttributes)); + "Found explicit ContextLoader class [%s] for context configuration attributes %s", + contextLoaderClass.getName(), configAttributes)); } return contextLoaderClass; } diff --git a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java index 9e113f5c18c..913986a4402 100644 --- a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java +++ b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java @@ -98,11 +98,10 @@ public abstract class MetaAnnotationUtils { * @return the corresponding annotation descriptor if the annotation was found; * otherwise {@code null} */ - private static AnnotationDescriptor findAnnotationDescriptor(Class clazz, - Set visited, Class annotationType) { + private static AnnotationDescriptor findAnnotationDescriptor( + Class clazz, Set visited, Class annotationType) { Assert.notNull(annotationType, "Annotation type must not be null"); - if (clazz == null || Object.class == clazz) { return null; } @@ -115,11 +114,11 @@ public abstract class MetaAnnotationUtils { // Declared on a composed annotation (i.e., as a meta-annotation)? for (Annotation composedAnnotation : clazz.getDeclaredAnnotations()) { if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedAnnotation) && visited.add(composedAnnotation)) { - AnnotationDescriptor descriptor = findAnnotationDescriptor(composedAnnotation.annotationType(), - visited, annotationType); + AnnotationDescriptor descriptor = findAnnotationDescriptor( + composedAnnotation.annotationType(), visited, annotationType); if (descriptor != null) { - return new AnnotationDescriptor(clazz, descriptor.getDeclaringClass(), composedAnnotation, - descriptor.getAnnotation()); + return new AnnotationDescriptor( + clazz, descriptor.getDeclaringClass(), composedAnnotation, descriptor.getAnnotation()); } } } @@ -287,8 +286,8 @@ public abstract class MetaAnnotationUtils { this.declaringClass = declaringClass; this.composedAnnotation = composedAnnotation; this.annotation = annotation; - this.annotationAttributes = AnnotatedElementUtils.findMergedAnnotationAttributes(rootDeclaringClass, - annotation.annotationType().getName(), false, false); + this.annotationAttributes = AnnotatedElementUtils.findMergedAnnotationAttributes( + rootDeclaringClass, annotation.annotationType().getName(), false, false); } public Class getRootDeclaringClass() { @@ -314,8 +313,8 @@ public abstract class MetaAnnotationUtils { */ @SuppressWarnings("unchecked") public T synthesizeAnnotation() { - return AnnotationUtils.synthesizeAnnotation(getAnnotationAttributes(), (Class) getAnnotationType(), - getRootDeclaringClass()); + return AnnotationUtils.synthesizeAnnotation( + getAnnotationAttributes(), (Class) getAnnotationType(), getRootDeclaringClass()); } public Class getAnnotationType() { diff --git a/spring-test/src/test/java/org/springframework/test/context/TestExecutionListenersTests.java b/spring-test/src/test/java/org/springframework/test/context/TestExecutionListenersTests.java index 886f2526403..648655fb9cf 100644 --- a/spring-test/src/test/java/org/springframework/test/context/TestExecutionListenersTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/TestExecutionListenersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 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. @@ -55,9 +55,9 @@ public class TestExecutionListenersTests { @Test public void defaultListeners() { List> expected = asList(ServletTestExecutionListener.class, - DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, - DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, - SqlScriptsTestExecutionListener.class); + DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, + DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, + SqlScriptsTestExecutionListener.class); assertRegisteredListeners(DefaultListenersTestCase.class, expected); } @@ -67,9 +67,9 @@ public class TestExecutionListenersTests { @Test public void defaultListenersMergedWithCustomListenerPrepended() { List> expected = asList(QuuxTestExecutionListener.class, ServletTestExecutionListener.class, - DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, - DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, - SqlScriptsTestExecutionListener.class); + DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, + DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, + SqlScriptsTestExecutionListener.class); assertRegisteredListeners(MergedDefaultListenersWithCustomListenerPrependedTestCase.class, expected); } @@ -79,9 +79,9 @@ public class TestExecutionListenersTests { @Test public void defaultListenersMergedWithCustomListenerAppended() { List> expected = asList(ServletTestExecutionListener.class, - DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, - DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, - SqlScriptsTestExecutionListener.class, BazTestExecutionListener.class); + DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, + DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class, + SqlScriptsTestExecutionListener.class, BazTestExecutionListener.class); assertRegisteredListeners(MergedDefaultListenersWithCustomListenerAppendedTestCase.class, expected); } @@ -91,9 +91,9 @@ public class TestExecutionListenersTests { @Test public void defaultListenersMergedWithCustomListenerInserted() { List> expected = asList(ServletTestExecutionListener.class, - DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, - BarTestExecutionListener.class, DirtiesContextTestExecutionListener.class, - TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class); + DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, + BarTestExecutionListener.class, DirtiesContextTestExecutionListener.class, + TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class); assertRegisteredListeners(MergedDefaultListenersWithCustomListenerInsertedTestCase.class, expected); } @@ -107,7 +107,7 @@ public class TestExecutionListenersTests { assertRegisteredListeners(InheritedDefaultListenersTestCase.class, asList(QuuxTestExecutionListener.class)); assertRegisteredListeners(SubInheritedDefaultListenersTestCase.class, asList(QuuxTestExecutionListener.class)); assertRegisteredListeners(SubSubInheritedDefaultListenersTestCase.class, - asList(QuuxTestExecutionListener.class, EnigmaTestExecutionListener.class)); + asList(QuuxTestExecutionListener.class, EnigmaTestExecutionListener.class)); } @Test @@ -172,13 +172,13 @@ public class TestExecutionListenersTests { private void assertRegisteredListeners(Class testClass, List> expected) { TestContextManager testContextManager = new TestContextManager(testClass); assertEquals("TELs registered for " + testClass.getSimpleName(), names(expected), - names(classes(testContextManager))); + names(classes(testContextManager))); } private void assertNumRegisteredListeners(Class testClass, int expected) { TestContextManager testContextManager = new TestContextManager(testClass); assertEquals("Num registered TELs for " + testClass, expected, - testContextManager.getTestExecutionListeners().size()); + testContextManager.getTestExecutionListeners().size()); } @@ -187,8 +187,9 @@ public class TestExecutionListenersTests { static class DefaultListenersTestCase { } - @TestExecutionListeners(listeners = { QuuxTestExecutionListener.class, - DependencyInjectionTestExecutionListener.class }, mergeMode = MERGE_WITH_DEFAULTS) + @TestExecutionListeners( + listeners = {QuuxTestExecutionListener.class, DependencyInjectionTestExecutionListener.class}, + mergeMode = MERGE_WITH_DEFAULTS) static class MergedDefaultListenersWithCustomListenerPrependedTestCase { } @@ -211,12 +212,12 @@ public class TestExecutionListenersTests { static class SubSubInheritedDefaultListenersTestCase extends SubInheritedDefaultListenersTestCase { } - @TestExecutionListeners(listeners = { QuuxTestExecutionListener.class }, inheritListeners = false) + @TestExecutionListeners(listeners = QuuxTestExecutionListener.class, inheritListeners = false) static class NonInheritedDefaultListenersTestCase extends InheritedDefaultListenersTestCase { } - @TestExecutionListeners({ FooTestExecutionListener.class, BarTestExecutionListener.class, - BazTestExecutionListener.class }) + @TestExecutionListeners( + {FooTestExecutionListener.class, BarTestExecutionListener.class, BazTestExecutionListener.class}) static class ExplicitListenersTestCase { } @@ -232,36 +233,36 @@ public class TestExecutionListenersTests { static class DuplicateListenersConfigTestCase { } - @TestExecutionListeners({// - FooTestExecutionListener.class,// - BarTestExecutionListener.class,// - BazTestExecutionListener.class // + @TestExecutionListeners({ + FooTestExecutionListener.class, + BarTestExecutionListener.class, + BazTestExecutionListener.class }) @Retention(RetentionPolicy.RUNTIME) - static @interface MetaListeners { + @interface MetaListeners { } @TestExecutionListeners(QuuxTestExecutionListener.class) @Retention(RetentionPolicy.RUNTIME) - static @interface MetaInheritedListeners { + @interface MetaInheritedListeners { } @TestExecutionListeners(listeners = QuuxTestExecutionListener.class, inheritListeners = false) @Retention(RetentionPolicy.RUNTIME) - static @interface MetaNonInheritedListeners { + @interface MetaNonInheritedListeners { } @TestExecutionListeners @Retention(RetentionPolicy.RUNTIME) - static @interface MetaListenersWithOverrides { + @interface MetaListenersWithOverrides { - Class[] listeners() default { FooTestExecutionListener.class, - BarTestExecutionListener.class }; + Class[] listeners() default + {FooTestExecutionListener.class, BarTestExecutionListener.class}; } @TestExecutionListeners @Retention(RetentionPolicy.RUNTIME) - static @interface MetaInheritedListenersWithOverrides { + @interface MetaInheritedListenersWithOverrides { Class[] listeners() default QuuxTestExecutionListener.class; @@ -270,7 +271,7 @@ public class TestExecutionListenersTests { @TestExecutionListeners @Retention(RetentionPolicy.RUNTIME) - static @interface MetaNonInheritedListenersWithOverrides { + @interface MetaNonInheritedListenersWithOverrides { Class[] listeners() default QuuxTestExecutionListener.class; @@ -289,24 +290,23 @@ public class TestExecutionListenersTests { static class MetaNonInheritedListenersTestCase extends MetaInheritedListenersTestCase { } - @MetaListenersWithOverrides(listeners = {// - FooTestExecutionListener.class,// - BarTestExecutionListener.class,// - BazTestExecutionListener.class // + @MetaListenersWithOverrides(listeners = { + FooTestExecutionListener.class, + BarTestExecutionListener.class, + BazTestExecutionListener.class }) static class MetaWithOverridesTestCase { } - @MetaInheritedListenersWithOverrides(listeners = { FooTestExecutionListener.class, BarTestExecutionListener.class }) + @MetaInheritedListenersWithOverrides(listeners = {FooTestExecutionListener.class, BarTestExecutionListener.class}) static class MetaInheritedListenersWithOverridesTestCase extends MetaWithOverridesTestCase { } - @MetaNonInheritedListenersWithOverrides(listeners = {// - FooTestExecutionListener.class,// - BarTestExecutionListener.class,// - BazTestExecutionListener.class // - },// - inheritListeners = true) + @MetaNonInheritedListenersWithOverrides(listeners = { + FooTestExecutionListener.class, + BarTestExecutionListener.class, + BazTestExecutionListener.class + }, inheritListeners = true) static class MetaNonInheritedListenersWithOverridesTestCase extends MetaInheritedListenersWithOverridesTestCase { } @@ -342,4 +342,4 @@ public class TestExecutionListenersTests { static class EnigmaTestExecutionListener extends AbstractTestExecutionListener { } -} \ No newline at end of file +}