Polishing
This commit is contained in:
@@ -43,51 +43,47 @@ import static org.springframework.beans.BeanUtils.instantiateClass;
|
|||||||
*/
|
*/
|
||||||
abstract class BootstrapUtils {
|
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 static final Log logger = LogFactory.getLog(BootstrapUtils.class);
|
||||||
|
|
||||||
|
|
||||||
private BootstrapUtils() {
|
|
||||||
/* no-op */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the {@code BootstrapContext} for the specified {@linkplain Class test class}.
|
* Create the {@code BootstrapContext} for the specified {@linkplain Class test class}.
|
||||||
*
|
|
||||||
* <p>Uses reflection to create a {@link org.springframework.test.context.support.DefaultBootstrapContext}
|
* <p>Uses reflection to create a {@link org.springframework.test.context.support.DefaultBootstrapContext}
|
||||||
* that uses a {@link org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate}.
|
* that uses a {@link org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate}.
|
||||||
*
|
|
||||||
* @param testClass the test class for which the bootstrap context should be created
|
* @param testClass the test class for which the bootstrap context should be created
|
||||||
* @return a new {@code BootstrapContext}; never {@code null}
|
* @return a new {@code BootstrapContext}; never {@code null}
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
static BootstrapContext createBootstrapContext(Class<?> testClass) {
|
static BootstrapContext createBootstrapContext(Class<?> testClass) {
|
||||||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = createCacheAwareContextLoaderDelegate();
|
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = createCacheAwareContextLoaderDelegate();
|
||||||
|
|
||||||
Class<? extends BootstrapContext> clazz = null;
|
Class<? extends BootstrapContext> clazz = null;
|
||||||
try {
|
try {
|
||||||
clazz = (Class<? extends BootstrapContext>) ClassUtils.forName(DEFAULT_BOOTSTRAP_CONTEXT_CLASS_NAME,
|
clazz = (Class<? extends BootstrapContext>) ClassUtils.forName(
|
||||||
BootstrapUtils.class.getClassLoader());
|
DEFAULT_BOOTSTRAP_CONTEXT_CLASS_NAME, BootstrapUtils.class.getClassLoader());
|
||||||
|
Constructor<? extends BootstrapContext> constructor = clazz.getConstructor(
|
||||||
Constructor<? extends BootstrapContext> constructor = clazz.getConstructor(Class.class,
|
Class.class, CacheAwareContextLoaderDelegate.class);
|
||||||
CacheAwareContextLoaderDelegate.class);
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("Instantiating BootstrapContext using constructor [%s]", constructor));
|
logger.debug(String.format("Instantiating BootstrapContext using constructor [%s]", constructor));
|
||||||
}
|
}
|
||||||
return instantiateClass(constructor, testClass, cacheAwareContextLoaderDelegate);
|
return instantiateClass(constructor, testClass, cacheAwareContextLoaderDelegate);
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable ex) {
|
||||||
throw new IllegalStateException("Could not load BootstrapContext [" + clazz + "]", t);
|
throw new IllegalStateException("Could not load BootstrapContext [" + clazz + "]", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,8 +100,8 @@ abstract class BootstrapUtils {
|
|||||||
}
|
}
|
||||||
return instantiateClass(clazz, CacheAwareContextLoaderDelegate.class);
|
return instantiateClass(clazz, CacheAwareContextLoaderDelegate.class);
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable ex) {
|
||||||
throw new IllegalStateException("Could not load CacheAwareContextLoaderDelegate [" + clazz + "]", t);
|
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
|
* Resolve the {@link TestContextBootstrapper} type for the test class in the
|
||||||
* supplied {@link BootstrapContext}, instantiate it, and provide it a reference
|
* supplied {@link BootstrapContext}, instantiate it, and provide it a reference
|
||||||
* to the {@link BootstrapContext}.
|
* to the {@link BootstrapContext}.
|
||||||
*
|
|
||||||
* <p>If the {@link BootstrapWith @BootstrapWith} annotation is present on
|
* <p>If the {@link BootstrapWith @BootstrapWith} annotation is present on
|
||||||
* the test class, either directly or as a meta-annotation, then its
|
* the test class, either directly or as a meta-annotation, then its
|
||||||
* {@link BootstrapWith#value value} will be used as the bootstrapper type.
|
* {@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
|
* {@link org.springframework.test.context.web.WebTestContextBootstrapper
|
||||||
* WebTestContextBootstrapper} will be used, depending on the presence of
|
* WebTestContextBootstrapper} will be used, depending on the presence of
|
||||||
* {@link org.springframework.test.context.web.WebAppConfiguration @WebAppConfiguration}.
|
* {@link org.springframework.test.context.web.WebAppConfiguration @WebAppConfiguration}.
|
||||||
*
|
|
||||||
* @param bootstrapContext the bootstrap context to use
|
* @param bootstrapContext the bootstrap context to use
|
||||||
* @return a fully configured {@code TestContextBootstrapper}
|
* @return a fully configured {@code TestContextBootstrapper}
|
||||||
*/
|
*/
|
||||||
@@ -138,21 +132,19 @@ abstract class BootstrapUtils {
|
|||||||
}
|
}
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("Instantiating TestContextBootstrapper for test class [%s] from class [%s]",
|
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 testContextBootstrapper = instantiateClass(clazz, TestContextBootstrapper.class);
|
||||||
testContextBootstrapper.setBootstrapContext(bootstrapContext);
|
testContextBootstrapper.setBootstrapContext(bootstrapContext);
|
||||||
|
|
||||||
return testContextBootstrapper;
|
return testContextBootstrapper;
|
||||||
}
|
}
|
||||||
catch (Throwable ex) {
|
catch (Throwable ex) {
|
||||||
if (ex instanceof IllegalStateException) {
|
if (ex instanceof IllegalStateException) {
|
||||||
throw (IllegalStateException) ex;
|
throw (IllegalStateException) ex;
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Could not load TestContextBootstrapper [" + clazz
|
throw new IllegalStateException("Could not load TestContextBootstrapper [" + clazz +
|
||||||
+ "]. Specify @BootstrapWith's 'value' attribute "
|
"]. Specify @BootstrapWith's 'value' attribute or make the default bootstrapper class available.",
|
||||||
+ "or make the default bootstrapper class available.", ex);
|
ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,14 +152,16 @@ abstract class BootstrapUtils {
|
|||||||
* @since 4.3
|
* @since 4.3
|
||||||
*/
|
*/
|
||||||
private static Class<?> resolveExplicitTestContextBootstrapper(Class<?> testClass) {
|
private static Class<?> resolveExplicitTestContextBootstrapper(Class<?> testClass) {
|
||||||
MultiValueMap<String, Object> attributesMultiMap = AnnotatedElementUtils.getAllAnnotationAttributes(
|
MultiValueMap<String, Object> attributesMultiMap =
|
||||||
testClass, BootstrapWith.class.getName());
|
AnnotatedElementUtils.getAllAnnotationAttributes(testClass, BootstrapWith.class.getName());
|
||||||
List<Object> values = (attributesMultiMap == null ? null : attributesMultiMap.get(AnnotationUtils.VALUE));
|
List<Object> values = (attributesMultiMap != null ? attributesMultiMap.get(AnnotationUtils.VALUE) : null);
|
||||||
if (values == null) {
|
if (values == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Assert.state(values.size() == 1, String.format("Configuration error: found multiple declarations of "
|
if (values.size() != 1) {
|
||||||
+ "@BootstrapWith on test class [%s] with values %s", testClass.getName(), values));
|
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);
|
return (Class<?>) values.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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 <em>listener</em> API for reacting to
|
* {@code TestExecutionListener} defines a <em>listener</em> API for reacting to
|
||||||
* test execution events published by the {@link TestContextManager} with which
|
* test execution events published by the {@link TestContextManager} with which
|
||||||
* the listener is registered.
|
* the listener is registered.
|
||||||
|
*
|
||||||
* <p>Concrete implementations must provide a {@code public} no-args constructor,
|
* <p>Concrete implementations must provide a {@code public} no-args constructor,
|
||||||
* so that listeners can be instantiated transparently by tools and configuration
|
* so that listeners can be instantiated transparently by tools and configuration
|
||||||
* mechanisms.
|
* mechanisms.
|
||||||
|
*
|
||||||
* <p>Implementations may optionally declare the position in which they should
|
* <p>Implementations may optionally declare the position in which they should
|
||||||
* be ordered among the chain of default listeners via the
|
* be ordered among the chain of default listeners via the
|
||||||
* {@link org.springframework.core.Ordered Ordered} interface or
|
* {@link org.springframework.core.Ordered Ordered} interface or
|
||||||
* {@link org.springframework.core.annotation.Order @Order} annotation. See
|
* {@link org.springframework.core.annotation.Order @Order} annotation. See
|
||||||
* {@link TestContextBootstrapper#getTestExecutionListeners()} for details.
|
* {@link TestContextBootstrapper#getTestExecutionListeners()} for details.
|
||||||
|
*
|
||||||
* <p>Spring provides the following out-of-the-box implementations (all of
|
* <p>Spring provides the following out-of-the-box implementations (all of
|
||||||
* which implement {@code Ordered}):
|
* which implement {@code Ordered}):
|
||||||
* <ul>
|
* <ul>
|
||||||
@@ -58,7 +61,6 @@ public interface TestExecutionListener {
|
|||||||
* <em>before class</em> lifecycle callbacks.
|
* <em>before class</em> lifecycle callbacks.
|
||||||
* <p>If a given testing framework does not support <em>before class</em>
|
* <p>If a given testing framework does not support <em>before class</em>
|
||||||
* lifecycle callbacks, this method will not be called for that framework.
|
* lifecycle callbacks, this method will not be called for that framework.
|
||||||
*
|
|
||||||
* @param testContext the test context for the test; never {@code null}
|
* @param testContext the test context for the test; never {@code null}
|
||||||
* @throws Exception allows any exception to propagate
|
* @throws Exception allows any exception to propagate
|
||||||
*/
|
*/
|
||||||
@@ -69,7 +71,6 @@ public interface TestExecutionListener {
|
|||||||
* {@link TestContext test context}, for example by injecting dependencies.
|
* {@link TestContext test context}, for example by injecting dependencies.
|
||||||
* <p>This method should be called immediately after instantiation of the test
|
* <p>This method should be called immediately after instantiation of the test
|
||||||
* instance but prior to any framework-specific lifecycle callbacks.
|
* instance but prior to any framework-specific lifecycle callbacks.
|
||||||
*
|
|
||||||
* @param testContext the test context for the test; never {@code null}
|
* @param testContext the test context for the test; never {@code null}
|
||||||
* @throws Exception allows any exception to propagate
|
* @throws Exception allows any exception to propagate
|
||||||
*/
|
*/
|
||||||
@@ -82,7 +83,6 @@ public interface TestExecutionListener {
|
|||||||
* fixtures.
|
* fixtures.
|
||||||
* <p>This method should be called immediately prior to framework-specific
|
* <p>This method should be called immediately prior to framework-specific
|
||||||
* <em>before</em> lifecycle callbacks.
|
* <em>before</em> lifecycle callbacks.
|
||||||
*
|
|
||||||
* @param testContext the test context in which the test method will be
|
* @param testContext the test context in which the test method will be
|
||||||
* executed; never {@code null}
|
* executed; never {@code null}
|
||||||
* @throws Exception allows any exception to propagate
|
* @throws Exception allows any exception to propagate
|
||||||
@@ -96,7 +96,6 @@ public interface TestExecutionListener {
|
|||||||
* fixtures.
|
* fixtures.
|
||||||
* <p>This method should be called immediately after framework-specific
|
* <p>This method should be called immediately after framework-specific
|
||||||
* <em>after</em> lifecycle callbacks.
|
* <em>after</em> lifecycle callbacks.
|
||||||
*
|
|
||||||
* @param testContext the test context in which the test method was
|
* @param testContext the test context in which the test method was
|
||||||
* executed; never {@code null}
|
* executed; never {@code null}
|
||||||
* @throws Exception allows any exception to propagate
|
* @throws Exception allows any exception to propagate
|
||||||
@@ -110,7 +109,6 @@ public interface TestExecutionListener {
|
|||||||
* <em>after class</em> lifecycle callbacks.
|
* <em>after class</em> lifecycle callbacks.
|
||||||
* <p>If a given testing framework does not support <em>after class</em>
|
* <p>If a given testing framework does not support <em>after class</em>
|
||||||
* lifecycle callbacks, this method will not be called for that framework.
|
* lifecycle callbacks, this method will not be called for that framework.
|
||||||
*
|
|
||||||
* @param testContext the test context for the test; never {@code null}
|
* @param testContext the test context for the test; never {@code null}
|
||||||
* @throws Exception allows any exception to propagate
|
* @throws Exception allows any exception to propagate
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* which {@link TestExecutionListener TestExecutionListeners} should be
|
||||||
* registered with a {@link TestContextManager}.
|
* registered with a {@link TestContextManager}.
|
||||||
*
|
*
|
||||||
* <p>Typically, {@code @TestExecutionListeners} will be used in conjunction with
|
* <p>Typically, {@code @TestExecutionListeners} will be used in conjunction
|
||||||
* {@link ContextConfiguration @ContextConfiguration}.
|
* with {@link ContextConfiguration @ContextConfiguration}.
|
||||||
*
|
*
|
||||||
* <p>As of Spring Framework 4.0, this annotation may be used as a
|
* <p>As of Spring Framework 4.0, this annotation may be used as a
|
||||||
* <em>meta-annotation</em> to create custom <em>composed annotations</em>.
|
* <em>meta-annotation</em> to create custom <em>composed annotations</em>.
|
||||||
@@ -48,6 +48,78 @@ import org.springframework.core.annotation.AliasFor;
|
|||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
public @interface TestExecutionListeners {
|
public @interface TestExecutionListeners {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for {@link #listeners}.
|
||||||
|
* <p>This attribute may <strong>not</strong> be used in conjunction with
|
||||||
|
* {@link #listeners}, but it may be used instead of {@link #listeners}.
|
||||||
|
*/
|
||||||
|
@AliasFor("listeners")
|
||||||
|
Class<? extends TestExecutionListener>[] value() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link TestExecutionListener TestExecutionListeners} to register with
|
||||||
|
* the {@link TestContextManager}.
|
||||||
|
* <p>This attribute may <strong>not</strong> 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
|
||||||
|
* @see org.springframework.test.context.transaction.TransactionalTestExecutionListener
|
||||||
|
* @see org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener
|
||||||
|
*/
|
||||||
|
@AliasFor("value")
|
||||||
|
Class<? extends TestExecutionListener>[] listeners() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not {@link #listeners TestExecutionListeners} from superclasses
|
||||||
|
* should be <em>inherited</em>.
|
||||||
|
* <p>The default value is {@code true}, which means that an annotated
|
||||||
|
* class will <em>inherit</em> the listeners defined by an annotated
|
||||||
|
* superclass. Specifically, the listeners for an annotated class will be
|
||||||
|
* appended to the list of listeners defined by an annotated superclass.
|
||||||
|
* Thus, subclasses have the option of <em>extending</em> the list of
|
||||||
|
* listeners. In the following example, {@code AbstractBaseTest} will
|
||||||
|
* be configured with {@code DependencyInjectionTestExecutionListener}
|
||||||
|
* and {@code DirtiesContextTestExecutionListener}; whereas,
|
||||||
|
* {@code TransactionalTest} will be configured with
|
||||||
|
* {@code DependencyInjectionTestExecutionListener},
|
||||||
|
* {@code DirtiesContextTestExecutionListener}, <strong>and</strong>
|
||||||
|
* {@code TransactionalTestExecutionListener}, in that order.
|
||||||
|
* <pre class="code">
|
||||||
|
* @TestExecutionListeners({
|
||||||
|
* DependencyInjectionTestExecutionListener.class,
|
||||||
|
* DirtiesContextTestExecutionListener.class
|
||||||
|
* })
|
||||||
|
* public abstract class AbstractBaseTest {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @TestExecutionListeners(TransactionalTestExecutionListener.class)
|
||||||
|
* public class TransactionalTest extends AbstractBaseTest {
|
||||||
|
* // ...
|
||||||
|
* }</pre>
|
||||||
|
* <p>If {@code inheritListeners} is set to {@code false}, the listeners for
|
||||||
|
* the annotated class will <em>shadow</em> and effectively replace any
|
||||||
|
* listeners defined by a superclass.
|
||||||
|
*/
|
||||||
|
boolean inheritListeners() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The <em>merge mode</em> to use when {@code @TestExecutionListeners} is
|
||||||
|
* declared on a class that does <strong>not</strong> inherit listeners
|
||||||
|
* from a superclass.
|
||||||
|
* <p>Can be set to {@link MergeMode#MERGE_WITH_DEFAULTS MERGE_WITH_DEFAULTS}
|
||||||
|
* to have locally declared listeners <em>merged</em> with the default
|
||||||
|
* listeners.
|
||||||
|
* <p>The mode is ignored if listeners are inherited from a superclass.
|
||||||
|
* <p>Defaults to {@link MergeMode#REPLACE_DEFAULTS REPLACE_DEFAULTS}
|
||||||
|
* for backwards compatibility.
|
||||||
|
* @see MergeMode
|
||||||
|
* @since 4.1
|
||||||
|
*/
|
||||||
|
MergeMode mergeMode() default MergeMode.REPLACE_DEFAULTS;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumeration of <em>modes</em> that dictate whether or not explicitly
|
* Enumeration of <em>modes</em> that dictate whether or not explicitly
|
||||||
* declared listeners are merged with the default listeners when
|
* declared listeners are merged with the default listeners when
|
||||||
@@ -55,7 +127,7 @@ public @interface TestExecutionListeners {
|
|||||||
* <strong>not</strong> inherit listeners from a superclass.
|
* <strong>not</strong> inherit listeners from a superclass.
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
static enum MergeMode {
|
enum MergeMode {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that locally declared listeners should replace the default
|
* Indicates that locally declared listeners should replace the default
|
||||||
@@ -80,82 +152,4 @@ public @interface TestExecutionListeners {
|
|||||||
MERGE_WITH_DEFAULTS
|
MERGE_WITH_DEFAULTS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Alias for {@link #listeners}.
|
|
||||||
*
|
|
||||||
* <p>This attribute may <strong>not</strong> be used in conjunction with
|
|
||||||
* {@link #listeners}, but it may be used instead of {@link #listeners}.
|
|
||||||
*/
|
|
||||||
@AliasFor("listeners")
|
|
||||||
Class<? extends TestExecutionListener>[] value() default {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link TestExecutionListener TestExecutionListeners} to register with
|
|
||||||
* the {@link TestContextManager}.
|
|
||||||
*
|
|
||||||
* <p>This attribute may <strong>not</strong> 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
|
|
||||||
* @see org.springframework.test.context.transaction.TransactionalTestExecutionListener
|
|
||||||
* @see org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener
|
|
||||||
*/
|
|
||||||
@AliasFor("value")
|
|
||||||
Class<? extends TestExecutionListener>[] listeners() default {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not {@link #listeners TestExecutionListeners} from superclasses
|
|
||||||
* should be <em>inherited</em>.
|
|
||||||
*
|
|
||||||
* <p>The default value is {@code true}, which means that an annotated
|
|
||||||
* class will <em>inherit</em> the listeners defined by an annotated
|
|
||||||
* superclass. Specifically, the listeners for an annotated class will be
|
|
||||||
* appended to the list of listeners defined by an annotated superclass.
|
|
||||||
* Thus, subclasses have the option of <em>extending</em> the list of
|
|
||||||
* listeners. In the following example, {@code AbstractBaseTest} will
|
|
||||||
* be configured with {@code DependencyInjectionTestExecutionListener}
|
|
||||||
* and {@code DirtiesContextTestExecutionListener}; whereas,
|
|
||||||
* {@code TransactionalTest} will be configured with
|
|
||||||
* {@code DependencyInjectionTestExecutionListener},
|
|
||||||
* {@code DirtiesContextTestExecutionListener}, <strong>and</strong>
|
|
||||||
* {@code TransactionalTestExecutionListener}, in that order.
|
|
||||||
*
|
|
||||||
* <pre class="code">
|
|
||||||
* @TestExecutionListeners({
|
|
||||||
* DependencyInjectionTestExecutionListener.class,
|
|
||||||
* DirtiesContextTestExecutionListener.class
|
|
||||||
* })
|
|
||||||
* public abstract class AbstractBaseTest {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @TestExecutionListeners(TransactionalTestExecutionListener.class)
|
|
||||||
* public class TransactionalTest extends AbstractBaseTest {
|
|
||||||
* // ...
|
|
||||||
* }</pre>
|
|
||||||
*
|
|
||||||
* <p>If {@code inheritListeners} is set to {@code false}, the listeners for
|
|
||||||
* the annotated class will <em>shadow</em> and effectively replace any
|
|
||||||
* listeners defined by a superclass.
|
|
||||||
*/
|
|
||||||
boolean inheritListeners() default true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The <em>merge mode</em> to use when {@code @TestExecutionListeners} is
|
|
||||||
* declared on a class that does <strong>not</strong> inherit listeners
|
|
||||||
* from a superclass.
|
|
||||||
* <p>Can be set to {@link MergeMode#MERGE_WITH_DEFAULTS MERGE_WITH_DEFAULTS}
|
|
||||||
* to have locally declared listeners <em>merged</em> with the default
|
|
||||||
* listeners.
|
|
||||||
* <p>The mode is ignored if listeners are inherited from a superclass.
|
|
||||||
* <p>Defaults to {@link MergeMode#REPLACE_DEFAULTS REPLACE_DEFAULTS}
|
|
||||||
* for backwards compatibility.
|
|
||||||
* @see MergeMode
|
|
||||||
* @since 4.1
|
|
||||||
*/
|
|
||||||
MergeMode mergeMode() default MergeMode.REPLACE_DEFAULTS;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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}.
|
* Alias for {@link #locations}.
|
||||||
*
|
|
||||||
* <p>This attribute may <strong>not</strong> be used in conjunction with
|
* <p>This attribute may <strong>not</strong> be used in conjunction with
|
||||||
* {@link #locations}, but it may be used <em>instead</em> of {@link #locations}.
|
* {@link #locations}, but it may be used <em>instead</em> of {@link #locations}.
|
||||||
*
|
|
||||||
* @see #locations
|
* @see #locations
|
||||||
*/
|
*/
|
||||||
@AliasFor("locations")
|
@AliasFor("locations")
|
||||||
@@ -104,12 +102,10 @@ public @interface TestPropertySource {
|
|||||||
* {@code Environment}'s set of {@code PropertySources}. Each location
|
* {@code Environment}'s set of {@code PropertySources}. Each location
|
||||||
* will be added to the enclosing {@code Environment} as its own property
|
* will be added to the enclosing {@code Environment} as its own property
|
||||||
* source, in the order declared.
|
* source, in the order declared.
|
||||||
*
|
|
||||||
* <h3>Supported File Formats</h3>
|
* <h3>Supported File Formats</h3>
|
||||||
* <p>Both traditional and XML-based properties file formats are supported
|
* <p>Both traditional and XML-based properties file formats are supported
|
||||||
* — for example, {@code "classpath:/com/example/test.properties"}
|
* — for example, {@code "classpath:/com/example/test.properties"}
|
||||||
* or {@code "file:/path/to/file.xml"}.
|
* or {@code "file:/path/to/file.xml"}.
|
||||||
*
|
|
||||||
* <h3>Path Resource Semantics</h3>
|
* <h3>Path Resource Semantics</h3>
|
||||||
* <p>Each path will be interpreted as a Spring
|
* <p>Each path will be interpreted as a Spring
|
||||||
* {@link org.springframework.core.io.Resource Resource}. A plain path
|
* {@link org.springframework.core.io.Resource Resource}. A plain path
|
||||||
@@ -128,17 +124,13 @@ public @interface TestPropertySource {
|
|||||||
* in paths (i.e., <code>${...}</code>) will be
|
* in paths (i.e., <code>${...}</code>) will be
|
||||||
* {@linkplain org.springframework.core.env.Environment#resolveRequiredPlaceholders(String) resolved}
|
* {@linkplain org.springframework.core.env.Environment#resolveRequiredPlaceholders(String) resolved}
|
||||||
* against the {@code Environment}.
|
* against the {@code Environment}.
|
||||||
*
|
|
||||||
* <h3>Default Properties File Detection</h3>
|
* <h3>Default Properties File Detection</h3>
|
||||||
* <p>See the class-level Javadoc for a discussion on detection of defaults.
|
* <p>See the class-level Javadoc for a discussion on detection of defaults.
|
||||||
*
|
|
||||||
* <h3>Precedence</h3>
|
* <h3>Precedence</h3>
|
||||||
* <p>Properties loaded from resource locations have lower precedence than
|
* <p>Properties loaded from resource locations have lower precedence than
|
||||||
* inlined {@link #properties}.
|
* inlined {@link #properties}.
|
||||||
*
|
|
||||||
* <p>This attribute may <strong>not</strong> be used in conjunction with
|
* <p>This attribute may <strong>not</strong> be used in conjunction with
|
||||||
* {@link #value}, but it may be used <em>instead</em> of {@link #value}.
|
* {@link #value}, but it may be used <em>instead</em> of {@link #value}.
|
||||||
*
|
|
||||||
* @see #inheritLocations
|
* @see #inheritLocations
|
||||||
* @see #value
|
* @see #value
|
||||||
* @see #properties
|
* @see #properties
|
||||||
@@ -150,18 +142,15 @@ public @interface TestPropertySource {
|
|||||||
/**
|
/**
|
||||||
* Whether or not test property source {@link #locations} from superclasses
|
* Whether or not test property source {@link #locations} from superclasses
|
||||||
* should be <em>inherited</em>.
|
* should be <em>inherited</em>.
|
||||||
*
|
|
||||||
* <p>The default value is {@code true}, which means that a test class will
|
* <p>The default value is {@code true}, which means that a test class will
|
||||||
* <em>inherit</em> property source locations defined by a superclass.
|
* <em>inherit</em> property source locations defined by a superclass.
|
||||||
* Specifically, the property source locations for a test class will be
|
* Specifically, the property source locations for a test class will be
|
||||||
* appended to the list of property source locations defined by a superclass.
|
* appended to the list of property source locations defined by a superclass.
|
||||||
* Thus, subclasses have the option of <em>extending</em> the list of test
|
* Thus, subclasses have the option of <em>extending</em> the list of test
|
||||||
* property source locations.
|
* property source locations.
|
||||||
*
|
|
||||||
* <p>If {@code inheritLocations} is set to {@code false}, the property
|
* <p>If {@code inheritLocations} is set to {@code false}, the property
|
||||||
* source locations for the test class will <em>shadow</em> and effectively
|
* source locations for the test class will <em>shadow</em> and effectively
|
||||||
* replace any property source locations defined by a superclass.
|
* replace any property source locations defined by a superclass.
|
||||||
*
|
|
||||||
* <p>In the following example, the {@code ApplicationContext} for
|
* <p>In the following example, the {@code ApplicationContext} for
|
||||||
* {@code BaseTest} will be loaded using only the {@code "base.properties"}
|
* {@code BaseTest} will be loaded using only the {@code "base.properties"}
|
||||||
* file as a test property source. In contrast, the {@code ApplicationContext}
|
* file as a test property source. In contrast, the {@code ApplicationContext}
|
||||||
@@ -172,13 +161,13 @@ public @interface TestPropertySource {
|
|||||||
* @TestPropertySource("base.properties")
|
* @TestPropertySource("base.properties")
|
||||||
* @ContextConfiguration
|
* @ContextConfiguration
|
||||||
* public class BaseTest {
|
* public class BaseTest {
|
||||||
* // ...
|
* // ...
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @TestPropertySource("extended.properties")
|
* @TestPropertySource("extended.properties")
|
||||||
* @ContextConfiguration
|
* @ContextConfiguration
|
||||||
* public class ExtendedTest extends BaseTest {
|
* public class ExtendedTest extends BaseTest {
|
||||||
* // ...
|
* // ...
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
@@ -193,7 +182,6 @@ public @interface TestPropertySource {
|
|||||||
* {@code ApplicationContext} is loaded for the test. All key-value pairs
|
* {@code ApplicationContext} is loaded for the test. All key-value pairs
|
||||||
* will be added to the enclosing {@code Environment} as a single test
|
* will be added to the enclosing {@code Environment} as a single test
|
||||||
* {@code PropertySource} with the highest precedence.
|
* {@code PropertySource} with the highest precedence.
|
||||||
*
|
|
||||||
* <h3>Supported Syntax</h3>
|
* <h3>Supported Syntax</h3>
|
||||||
* <p>The supported syntax for key-value pairs is the same as the
|
* <p>The supported syntax for key-value pairs is the same as the
|
||||||
* syntax defined for entries in a Java
|
* syntax defined for entries in a Java
|
||||||
@@ -203,14 +191,11 @@ public @interface TestPropertySource {
|
|||||||
* <li>{@code "key:value"}</li>
|
* <li>{@code "key:value"}</li>
|
||||||
* <li>{@code "key value"}</li>
|
* <li>{@code "key value"}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
|
||||||
* <h3>Precedence</h3>
|
* <h3>Precedence</h3>
|
||||||
* <p>Properties declared via this attribute have higher precedence than
|
* <p>Properties declared via this attribute have higher precedence than
|
||||||
* properties loaded from resource {@link #locations}.
|
* properties loaded from resource {@link #locations}.
|
||||||
*
|
|
||||||
* <p>This attribute may be used in conjunction with {@link #value}
|
* <p>This attribute may be used in conjunction with {@link #value}
|
||||||
* <em>or</em> {@link #locations}.
|
* <em>or</em> {@link #locations}.
|
||||||
*
|
|
||||||
* @see #inheritProperties
|
* @see #inheritProperties
|
||||||
* @see #locations
|
* @see #locations
|
||||||
* @see org.springframework.core.env.PropertySource
|
* @see org.springframework.core.env.PropertySource
|
||||||
@@ -220,17 +205,14 @@ public @interface TestPropertySource {
|
|||||||
/**
|
/**
|
||||||
* Whether or not inlined test {@link #properties} from superclasses should
|
* Whether or not inlined test {@link #properties} from superclasses should
|
||||||
* be <em>inherited</em>.
|
* be <em>inherited</em>.
|
||||||
*
|
|
||||||
* <p>The default value is {@code true}, which means that a test class will
|
* <p>The default value is {@code true}, which means that a test class will
|
||||||
* <em>inherit</em> inlined properties defined by a superclass. Specifically,
|
* <em>inherit</em> inlined properties defined by a superclass. Specifically,
|
||||||
* the inlined properties for a test class will be appended to the list of
|
* the inlined properties for a test class will be appended to the list of
|
||||||
* inlined properties defined by a superclass. Thus, subclasses have the
|
* inlined properties defined by a superclass. Thus, subclasses have the
|
||||||
* option of <em>extending</em> the list of inlined test properties.
|
* option of <em>extending</em> the list of inlined test properties.
|
||||||
*
|
|
||||||
* <p>If {@code inheritProperties} is set to {@code false}, the inlined
|
* <p>If {@code inheritProperties} is set to {@code false}, the inlined
|
||||||
* properties for the test class will <em>shadow</em> and effectively
|
* properties for the test class will <em>shadow</em> and effectively
|
||||||
* replace any inlined properties defined by a superclass.
|
* replace any inlined properties defined by a superclass.
|
||||||
*
|
|
||||||
* <p>In the following example, the {@code ApplicationContext} for
|
* <p>In the following example, the {@code ApplicationContext} for
|
||||||
* {@code BaseTest} will be loaded using only the inlined {@code key1}
|
* {@code BaseTest} will be loaded using only the inlined {@code key1}
|
||||||
* property. In contrast, the {@code ApplicationContext} for
|
* property. In contrast, the {@code ApplicationContext} for
|
||||||
@@ -240,16 +222,14 @@ public @interface TestPropertySource {
|
|||||||
* @TestPropertySource(properties = "key1 = value1")
|
* @TestPropertySource(properties = "key1 = value1")
|
||||||
* @ContextConfiguration
|
* @ContextConfiguration
|
||||||
* public class BaseTest {
|
* public class BaseTest {
|
||||||
* // ...
|
* // ...
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
* @TestPropertySource(properties = "key2 = value2")
|
* @TestPropertySource(properties = "key2 = value2")
|
||||||
* @ContextConfiguration
|
* @ContextConfiguration
|
||||||
* public class ExtendedTest extends BaseTest {
|
* public class ExtendedTest extends BaseTest {
|
||||||
* // ...
|
* // ...
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
|
||||||
* @see #properties
|
* @see #properties
|
||||||
*/
|
*/
|
||||||
boolean inheritProperties() default true;
|
boolean inheritProperties() default true;
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
@Override
|
@Override
|
||||||
public TestContext buildTestContext() {
|
public TestContext buildTestContext() {
|
||||||
return new DefaultTestContext(getBootstrapContext().getTestClass(), buildMergedContextConfiguration(),
|
return new DefaultTestContext(getBootstrapContext().getTestClass(), buildMergedContextConfiguration(),
|
||||||
getCacheAwareContextLoaderDelegate());
|
getCacheAwareContextLoaderDelegate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,14 +123,14 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
List<Class<? extends TestExecutionListener>> classesList = new ArrayList<Class<? extends TestExecutionListener>>();
|
List<Class<? extends TestExecutionListener>> classesList = new ArrayList<Class<? extends TestExecutionListener>>();
|
||||||
boolean usingDefaults = false;
|
boolean usingDefaults = false;
|
||||||
|
|
||||||
AnnotationDescriptor<TestExecutionListeners> descriptor = MetaAnnotationUtils.findAnnotationDescriptor(clazz,
|
AnnotationDescriptor<TestExecutionListeners> descriptor =
|
||||||
annotationType);
|
MetaAnnotationUtils.findAnnotationDescriptor(clazz, annotationType);
|
||||||
|
|
||||||
// Use defaults?
|
// Use defaults?
|
||||||
if (descriptor == null) {
|
if (descriptor == null) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format("@TestExecutionListeners is not present for class [%s]: using defaults.",
|
logger.debug(String.format("@TestExecutionListeners is not present for class [%s]: using defaults.",
|
||||||
clazz.getName()));
|
clazz.getName()));
|
||||||
}
|
}
|
||||||
usingDefaults = true;
|
usingDefaults = true;
|
||||||
classesList.addAll(getDefaultTestExecutionListenerClasses());
|
classesList.addAll(getDefaultTestExecutionListenerClasses());
|
||||||
@@ -142,21 +142,21 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
TestExecutionListeners testExecutionListeners = descriptor.synthesizeAnnotation();
|
TestExecutionListeners testExecutionListeners = descriptor.synthesizeAnnotation();
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("Retrieved @TestExecutionListeners [%s] for declaring class [%s].",
|
logger.trace(String.format("Retrieved @TestExecutionListeners [%s] for declaring class [%s].",
|
||||||
testExecutionListeners, declaringClass.getName()));
|
testExecutionListeners, declaringClass.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean inheritListeners = testExecutionListeners.inheritListeners();
|
boolean inheritListeners = testExecutionListeners.inheritListeners();
|
||||||
AnnotationDescriptor<TestExecutionListeners> superDescriptor = MetaAnnotationUtils.findAnnotationDescriptor(
|
AnnotationDescriptor<TestExecutionListeners> superDescriptor =
|
||||||
descriptor.getRootDeclaringClass().getSuperclass(), annotationType);
|
MetaAnnotationUtils.findAnnotationDescriptor(
|
||||||
|
descriptor.getRootDeclaringClass().getSuperclass(), annotationType);
|
||||||
|
|
||||||
// If there are no listeners to inherit, we might need to merge the
|
// If there are no listeners to inherit, we might need to merge the
|
||||||
// locally declared listeners with the defaults.
|
// locally declared listeners with the defaults.
|
||||||
if ((!inheritListeners || superDescriptor == null)
|
if ((!inheritListeners || superDescriptor == null) &&
|
||||||
&& (testExecutionListeners.mergeMode() == MergeMode.MERGE_WITH_DEFAULTS)) {
|
testExecutionListeners.mergeMode() == MergeMode.MERGE_WITH_DEFAULTS) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format(
|
logger.debug(String.format("Merging default listeners with listeners configured via " +
|
||||||
"Merging default listeners with listeners configured via @TestExecutionListeners for class [%s].",
|
"@TestExecutionListeners for class [%s].", descriptor.getRootDeclaringClass().getName()));
|
||||||
descriptor.getRootDeclaringClass().getName()));
|
|
||||||
}
|
}
|
||||||
usingDefaults = true;
|
usingDefaults = true;
|
||||||
classesList.addAll(getDefaultTestExecutionListenerClasses());
|
classesList.addAll(getDefaultTestExecutionListenerClasses());
|
||||||
@@ -206,10 +206,10 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
}
|
}
|
||||||
if (ncdfe != null) {
|
if (ncdfe != null) {
|
||||||
if (logger.isInfoEnabled()) {
|
if (logger.isInfoEnabled()) {
|
||||||
logger.info(String.format("Could not instantiate TestExecutionListener [%s]. "
|
logger.info(String.format("Could not instantiate TestExecutionListener [%s]. " +
|
||||||
+ "Specify custom listener classes or make the default listener classes "
|
"Specify custom listener classes or make the default listener classes " +
|
||||||
+ "(and their required dependencies) available. Offending class: [%s]",
|
"(and their required dependencies) available. Offending class: [%s]",
|
||||||
listenerClass.getName(), ncdfe.getMessage()));
|
listenerClass.getName(), ncdfe.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,8 +234,8 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
}
|
}
|
||||||
catch (Throwable ex) {
|
catch (Throwable ex) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Could not load default TestExecutionListener class [" + className
|
logger.debug("Could not load default TestExecutionListener class [" + className +
|
||||||
+ "]. Specify custom listener classes or make the default listener classes available.", ex);
|
"]. 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
|
* @see SpringFactoriesLoader#loadFactoryNames
|
||||||
*/
|
*/
|
||||||
protected List<String> getDefaultTestExecutionListenerClassNames() {
|
protected List<String> getDefaultTestExecutionListenerClassNames() {
|
||||||
final List<String> classNames = SpringFactoriesLoader.loadFactoryNames(TestExecutionListener.class,
|
List<String> classNames =
|
||||||
getClass().getClassLoader());
|
SpringFactoriesLoader.loadFactoryNames(TestExecutionListener.class, getClass().getClassLoader());
|
||||||
|
|
||||||
if (logger.isInfoEnabled()) {
|
if (logger.isInfoEnabled()) {
|
||||||
logger.info(String.format("Loaded default TestExecutionListener class names from location [%s]: %s",
|
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);
|
return Collections.unmodifiableList(classNames);
|
||||||
}
|
}
|
||||||
@@ -273,13 +272,14 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
Class<?> testClass = getBootstrapContext().getTestClass();
|
Class<?> testClass = getBootstrapContext().getTestClass();
|
||||||
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = getCacheAwareContextLoaderDelegate();
|
CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate = getCacheAwareContextLoaderDelegate();
|
||||||
|
|
||||||
if (MetaAnnotationUtils.findAnnotationDescriptorForTypes(testClass, ContextConfiguration.class,
|
if (MetaAnnotationUtils.findAnnotationDescriptorForTypes(
|
||||||
ContextHierarchy.class) == null) {
|
testClass, ContextConfiguration.class, ContextHierarchy.class) == null) {
|
||||||
return buildDefaultMergedContextConfiguration(testClass, cacheAwareContextLoaderDelegate);
|
return buildDefaultMergedContextConfiguration(testClass, cacheAwareContextLoaderDelegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AnnotationUtils.findAnnotation(testClass, ContextHierarchy.class) != null) {
|
if (AnnotationUtils.findAnnotation(testClass, ContextHierarchy.class) != null) {
|
||||||
Map<String, List<ContextConfigurationAttributes>> hierarchyMap = ContextLoaderUtils.buildContextHierarchyMap(testClass);
|
Map<String, List<ContextConfigurationAttributes>> hierarchyMap =
|
||||||
|
ContextLoaderUtils.buildContextHierarchyMap(testClass);
|
||||||
MergedContextConfiguration parentConfig = null;
|
MergedContextConfiguration parentConfig = null;
|
||||||
MergedContextConfiguration mergedConfig = null;
|
MergedContextConfiguration mergedConfig = null;
|
||||||
|
|
||||||
@@ -293,8 +293,8 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
Assert.notEmpty(reversedList, "ContextConfigurationAttributes list must not be empty");
|
Assert.notEmpty(reversedList, "ContextConfigurationAttributes list must not be empty");
|
||||||
Class<?> declaringClass = reversedList.get(0).getDeclaringClass();
|
Class<?> declaringClass = reversedList.get(0).getDeclaringClass();
|
||||||
|
|
||||||
mergedConfig = buildMergedContextConfiguration(declaringClass, reversedList, parentConfig,
|
mergedConfig = buildMergedContextConfiguration(
|
||||||
cacheAwareContextLoaderDelegate, true);
|
declaringClass, reversedList, parentConfig, cacheAwareContextLoaderDelegate, true);
|
||||||
parentConfig = mergedConfig;
|
parentConfig = mergedConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,8 +303,8 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return buildMergedContextConfiguration(testClass,
|
return buildMergedContextConfiguration(testClass,
|
||||||
ContextLoaderUtils.resolveContextConfigurationAttributes(testClass), null,
|
ContextLoaderUtils.resolveContextConfigurationAttributes(testClass),
|
||||||
cacheAwareContextLoaderDelegate, true);
|
null, cacheAwareContextLoaderDelegate, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,14 +390,16 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
Set<ContextCustomizer> contextCustomizers = getContextCustomizers(testClass,
|
Set<ContextCustomizer> contextCustomizers = getContextCustomizers(testClass,
|
||||||
Collections.unmodifiableList(configAttributesList));
|
Collections.unmodifiableList(configAttributesList));
|
||||||
|
|
||||||
if (requireLocationsClassesOrInitializers && areAllEmpty(locations, classes, initializers, contextCustomizers)) {
|
if (requireLocationsClassesOrInitializers &&
|
||||||
|
areAllEmpty(locations, classes, initializers, contextCustomizers)) {
|
||||||
throw new IllegalStateException(String.format(
|
throw new IllegalStateException(String.format(
|
||||||
"%s was unable to detect defaults, and no ApplicationContextInitializers "
|
"%s was unable to detect defaults, and no ApplicationContextInitializers " +
|
||||||
+ "or ContextCustomizers were declared for context configuration attributes %s",
|
"or ContextCustomizers were declared for context configuration attributes %s",
|
||||||
contextLoader.getClass().getSimpleName(), configAttributesList));
|
contextLoader.getClass().getSimpleName(), configAttributesList));
|
||||||
}
|
}
|
||||||
|
|
||||||
MergedTestPropertySources mergedTestPropertySources = TestPropertySourceUtils.buildMergedTestPropertySources(testClass);
|
MergedTestPropertySources mergedTestPropertySources =
|
||||||
|
TestPropertySourceUtils.buildMergedTestPropertySources(testClass);
|
||||||
MergedContextConfiguration mergedConfig = new MergedContextConfiguration(testClass,
|
MergedContextConfiguration mergedConfig = new MergedContextConfiguration(testClass,
|
||||||
StringUtils.toStringArray(locations),
|
StringUtils.toStringArray(locations),
|
||||||
ClassUtils.toClassArray(classes),
|
ClassUtils.toClassArray(classes),
|
||||||
@@ -485,7 +487,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
}
|
}
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("Using ContextLoader class [%s] for test class [%s]",
|
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);
|
return BeanUtils.instantiateClass(contextLoaderClass, ContextLoader.class);
|
||||||
}
|
}
|
||||||
@@ -518,14 +520,14 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||||||
for (ContextConfigurationAttributes configAttributes : configAttributesList) {
|
for (ContextConfigurationAttributes configAttributes : configAttributesList) {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace(String.format("Resolving ContextLoader for context configuration attributes %s",
|
logger.trace(String.format("Resolving ContextLoader for context configuration attributes %s",
|
||||||
configAttributes));
|
configAttributes));
|
||||||
}
|
}
|
||||||
Class<? extends ContextLoader> contextLoaderClass = configAttributes.getContextLoaderClass();
|
Class<? extends ContextLoader> contextLoaderClass = configAttributes.getContextLoaderClass();
|
||||||
if (ContextLoader.class != contextLoaderClass) {
|
if (ContextLoader.class != contextLoaderClass) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(String.format(
|
logger.debug(String.format(
|
||||||
"Found explicit ContextLoader class [%s] for context configuration attributes %s",
|
"Found explicit ContextLoader class [%s] for context configuration attributes %s",
|
||||||
contextLoaderClass.getName(), configAttributes));
|
contextLoaderClass.getName(), configAttributes));
|
||||||
}
|
}
|
||||||
return contextLoaderClass;
|
return contextLoaderClass;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,11 +98,10 @@ public abstract class MetaAnnotationUtils {
|
|||||||
* @return the corresponding annotation descriptor if the annotation was found;
|
* @return the corresponding annotation descriptor if the annotation was found;
|
||||||
* otherwise {@code null}
|
* otherwise {@code null}
|
||||||
*/
|
*/
|
||||||
private static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDescriptor(Class<?> clazz,
|
private static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDescriptor(
|
||||||
Set<Annotation> visited, Class<T> annotationType) {
|
Class<?> clazz, Set<Annotation> visited, Class<T> annotationType) {
|
||||||
|
|
||||||
Assert.notNull(annotationType, "Annotation type must not be null");
|
Assert.notNull(annotationType, "Annotation type must not be null");
|
||||||
|
|
||||||
if (clazz == null || Object.class == clazz) {
|
if (clazz == null || Object.class == clazz) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -115,11 +114,11 @@ public abstract class MetaAnnotationUtils {
|
|||||||
// Declared on a composed annotation (i.e., as a meta-annotation)?
|
// Declared on a composed annotation (i.e., as a meta-annotation)?
|
||||||
for (Annotation composedAnnotation : clazz.getDeclaredAnnotations()) {
|
for (Annotation composedAnnotation : clazz.getDeclaredAnnotations()) {
|
||||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedAnnotation) && visited.add(composedAnnotation)) {
|
if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedAnnotation) && visited.add(composedAnnotation)) {
|
||||||
AnnotationDescriptor<T> descriptor = findAnnotationDescriptor(composedAnnotation.annotationType(),
|
AnnotationDescriptor<T> descriptor = findAnnotationDescriptor(
|
||||||
visited, annotationType);
|
composedAnnotation.annotationType(), visited, annotationType);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
return new AnnotationDescriptor<T>(clazz, descriptor.getDeclaringClass(), composedAnnotation,
|
return new AnnotationDescriptor<T>(
|
||||||
descriptor.getAnnotation());
|
clazz, descriptor.getDeclaringClass(), composedAnnotation, descriptor.getAnnotation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,8 +286,8 @@ public abstract class MetaAnnotationUtils {
|
|||||||
this.declaringClass = declaringClass;
|
this.declaringClass = declaringClass;
|
||||||
this.composedAnnotation = composedAnnotation;
|
this.composedAnnotation = composedAnnotation;
|
||||||
this.annotation = annotation;
|
this.annotation = annotation;
|
||||||
this.annotationAttributes = AnnotatedElementUtils.findMergedAnnotationAttributes(rootDeclaringClass,
|
this.annotationAttributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
|
||||||
annotation.annotationType().getName(), false, false);
|
rootDeclaringClass, annotation.annotationType().getName(), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<?> getRootDeclaringClass() {
|
public Class<?> getRootDeclaringClass() {
|
||||||
@@ -314,8 +313,8 @@ public abstract class MetaAnnotationUtils {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public T synthesizeAnnotation() {
|
public T synthesizeAnnotation() {
|
||||||
return AnnotationUtils.synthesizeAnnotation(getAnnotationAttributes(), (Class<T>) getAnnotationType(),
|
return AnnotationUtils.synthesizeAnnotation(
|
||||||
getRootDeclaringClass());
|
getAnnotationAttributes(), (Class<T>) getAnnotationType(), getRootDeclaringClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<? extends Annotation> getAnnotationType() {
|
public Class<? extends Annotation> getAnnotationType() {
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -55,9 +55,9 @@ public class TestExecutionListenersTests {
|
|||||||
@Test
|
@Test
|
||||||
public void defaultListeners() {
|
public void defaultListeners() {
|
||||||
List<Class<?>> expected = asList(ServletTestExecutionListener.class,
|
List<Class<?>> expected = asList(ServletTestExecutionListener.class,
|
||||||
DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,
|
DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,
|
||||||
DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class,
|
DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class,
|
||||||
SqlScriptsTestExecutionListener.class);
|
SqlScriptsTestExecutionListener.class);
|
||||||
assertRegisteredListeners(DefaultListenersTestCase.class, expected);
|
assertRegisteredListeners(DefaultListenersTestCase.class, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,9 +67,9 @@ public class TestExecutionListenersTests {
|
|||||||
@Test
|
@Test
|
||||||
public void defaultListenersMergedWithCustomListenerPrepended() {
|
public void defaultListenersMergedWithCustomListenerPrepended() {
|
||||||
List<Class<?>> expected = asList(QuuxTestExecutionListener.class, ServletTestExecutionListener.class,
|
List<Class<?>> expected = asList(QuuxTestExecutionListener.class, ServletTestExecutionListener.class,
|
||||||
DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,
|
DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,
|
||||||
DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class,
|
DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class,
|
||||||
SqlScriptsTestExecutionListener.class);
|
SqlScriptsTestExecutionListener.class);
|
||||||
assertRegisteredListeners(MergedDefaultListenersWithCustomListenerPrependedTestCase.class, expected);
|
assertRegisteredListeners(MergedDefaultListenersWithCustomListenerPrependedTestCase.class, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,9 +79,9 @@ public class TestExecutionListenersTests {
|
|||||||
@Test
|
@Test
|
||||||
public void defaultListenersMergedWithCustomListenerAppended() {
|
public void defaultListenersMergedWithCustomListenerAppended() {
|
||||||
List<Class<?>> expected = asList(ServletTestExecutionListener.class,
|
List<Class<?>> expected = asList(ServletTestExecutionListener.class,
|
||||||
DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,
|
DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,
|
||||||
DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class,
|
DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class,
|
||||||
SqlScriptsTestExecutionListener.class, BazTestExecutionListener.class);
|
SqlScriptsTestExecutionListener.class, BazTestExecutionListener.class);
|
||||||
assertRegisteredListeners(MergedDefaultListenersWithCustomListenerAppendedTestCase.class, expected);
|
assertRegisteredListeners(MergedDefaultListenersWithCustomListenerAppendedTestCase.class, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,9 +91,9 @@ public class TestExecutionListenersTests {
|
|||||||
@Test
|
@Test
|
||||||
public void defaultListenersMergedWithCustomListenerInserted() {
|
public void defaultListenersMergedWithCustomListenerInserted() {
|
||||||
List<Class<?>> expected = asList(ServletTestExecutionListener.class,
|
List<Class<?>> expected = asList(ServletTestExecutionListener.class,
|
||||||
DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,
|
DirtiesContextBeforeModesTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,
|
||||||
BarTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
|
BarTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
|
||||||
TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class);
|
TransactionalTestExecutionListener.class, SqlScriptsTestExecutionListener.class);
|
||||||
assertRegisteredListeners(MergedDefaultListenersWithCustomListenerInsertedTestCase.class, expected);
|
assertRegisteredListeners(MergedDefaultListenersWithCustomListenerInsertedTestCase.class, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ public class TestExecutionListenersTests {
|
|||||||
assertRegisteredListeners(InheritedDefaultListenersTestCase.class, asList(QuuxTestExecutionListener.class));
|
assertRegisteredListeners(InheritedDefaultListenersTestCase.class, asList(QuuxTestExecutionListener.class));
|
||||||
assertRegisteredListeners(SubInheritedDefaultListenersTestCase.class, asList(QuuxTestExecutionListener.class));
|
assertRegisteredListeners(SubInheritedDefaultListenersTestCase.class, asList(QuuxTestExecutionListener.class));
|
||||||
assertRegisteredListeners(SubSubInheritedDefaultListenersTestCase.class,
|
assertRegisteredListeners(SubSubInheritedDefaultListenersTestCase.class,
|
||||||
asList(QuuxTestExecutionListener.class, EnigmaTestExecutionListener.class));
|
asList(QuuxTestExecutionListener.class, EnigmaTestExecutionListener.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -172,13 +172,13 @@ public class TestExecutionListenersTests {
|
|||||||
private void assertRegisteredListeners(Class<?> testClass, List<Class<?>> expected) {
|
private void assertRegisteredListeners(Class<?> testClass, List<Class<?>> expected) {
|
||||||
TestContextManager testContextManager = new TestContextManager(testClass);
|
TestContextManager testContextManager = new TestContextManager(testClass);
|
||||||
assertEquals("TELs registered for " + testClass.getSimpleName(), names(expected),
|
assertEquals("TELs registered for " + testClass.getSimpleName(), names(expected),
|
||||||
names(classes(testContextManager)));
|
names(classes(testContextManager)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertNumRegisteredListeners(Class<?> testClass, int expected) {
|
private void assertNumRegisteredListeners(Class<?> testClass, int expected) {
|
||||||
TestContextManager testContextManager = new TestContextManager(testClass);
|
TestContextManager testContextManager = new TestContextManager(testClass);
|
||||||
assertEquals("Num registered TELs for " + testClass, expected,
|
assertEquals("Num registered TELs for " + testClass, expected,
|
||||||
testContextManager.getTestExecutionListeners().size());
|
testContextManager.getTestExecutionListeners().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -187,8 +187,9 @@ public class TestExecutionListenersTests {
|
|||||||
static class DefaultListenersTestCase {
|
static class DefaultListenersTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestExecutionListeners(listeners = { QuuxTestExecutionListener.class,
|
@TestExecutionListeners(
|
||||||
DependencyInjectionTestExecutionListener.class }, mergeMode = MERGE_WITH_DEFAULTS)
|
listeners = {QuuxTestExecutionListener.class, DependencyInjectionTestExecutionListener.class},
|
||||||
|
mergeMode = MERGE_WITH_DEFAULTS)
|
||||||
static class MergedDefaultListenersWithCustomListenerPrependedTestCase {
|
static class MergedDefaultListenersWithCustomListenerPrependedTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,12 +212,12 @@ public class TestExecutionListenersTests {
|
|||||||
static class SubSubInheritedDefaultListenersTestCase extends SubInheritedDefaultListenersTestCase {
|
static class SubSubInheritedDefaultListenersTestCase extends SubInheritedDefaultListenersTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestExecutionListeners(listeners = { QuuxTestExecutionListener.class }, inheritListeners = false)
|
@TestExecutionListeners(listeners = QuuxTestExecutionListener.class, inheritListeners = false)
|
||||||
static class NonInheritedDefaultListenersTestCase extends InheritedDefaultListenersTestCase {
|
static class NonInheritedDefaultListenersTestCase extends InheritedDefaultListenersTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestExecutionListeners({ FooTestExecutionListener.class, BarTestExecutionListener.class,
|
@TestExecutionListeners(
|
||||||
BazTestExecutionListener.class })
|
{FooTestExecutionListener.class, BarTestExecutionListener.class, BazTestExecutionListener.class})
|
||||||
static class ExplicitListenersTestCase {
|
static class ExplicitListenersTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,36 +233,36 @@ public class TestExecutionListenersTests {
|
|||||||
static class DuplicateListenersConfigTestCase {
|
static class DuplicateListenersConfigTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestExecutionListeners({//
|
@TestExecutionListeners({
|
||||||
FooTestExecutionListener.class,//
|
FooTestExecutionListener.class,
|
||||||
BarTestExecutionListener.class,//
|
BarTestExecutionListener.class,
|
||||||
BazTestExecutionListener.class //
|
BazTestExecutionListener.class
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
static @interface MetaListeners {
|
@interface MetaListeners {
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestExecutionListeners(QuuxTestExecutionListener.class)
|
@TestExecutionListeners(QuuxTestExecutionListener.class)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
static @interface MetaInheritedListeners {
|
@interface MetaInheritedListeners {
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestExecutionListeners(listeners = QuuxTestExecutionListener.class, inheritListeners = false)
|
@TestExecutionListeners(listeners = QuuxTestExecutionListener.class, inheritListeners = false)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
static @interface MetaNonInheritedListeners {
|
@interface MetaNonInheritedListeners {
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestExecutionListeners
|
@TestExecutionListeners
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
static @interface MetaListenersWithOverrides {
|
@interface MetaListenersWithOverrides {
|
||||||
|
|
||||||
Class<? extends TestExecutionListener>[] listeners() default { FooTestExecutionListener.class,
|
Class<? extends TestExecutionListener>[] listeners() default
|
||||||
BarTestExecutionListener.class };
|
{FooTestExecutionListener.class, BarTestExecutionListener.class};
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestExecutionListeners
|
@TestExecutionListeners
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
static @interface MetaInheritedListenersWithOverrides {
|
@interface MetaInheritedListenersWithOverrides {
|
||||||
|
|
||||||
Class<? extends TestExecutionListener>[] listeners() default QuuxTestExecutionListener.class;
|
Class<? extends TestExecutionListener>[] listeners() default QuuxTestExecutionListener.class;
|
||||||
|
|
||||||
@@ -270,7 +271,7 @@ public class TestExecutionListenersTests {
|
|||||||
|
|
||||||
@TestExecutionListeners
|
@TestExecutionListeners
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
static @interface MetaNonInheritedListenersWithOverrides {
|
@interface MetaNonInheritedListenersWithOverrides {
|
||||||
|
|
||||||
Class<? extends TestExecutionListener>[] listeners() default QuuxTestExecutionListener.class;
|
Class<? extends TestExecutionListener>[] listeners() default QuuxTestExecutionListener.class;
|
||||||
|
|
||||||
@@ -289,24 +290,23 @@ public class TestExecutionListenersTests {
|
|||||||
static class MetaNonInheritedListenersTestCase extends MetaInheritedListenersTestCase {
|
static class MetaNonInheritedListenersTestCase extends MetaInheritedListenersTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@MetaListenersWithOverrides(listeners = {//
|
@MetaListenersWithOverrides(listeners = {
|
||||||
FooTestExecutionListener.class,//
|
FooTestExecutionListener.class,
|
||||||
BarTestExecutionListener.class,//
|
BarTestExecutionListener.class,
|
||||||
BazTestExecutionListener.class //
|
BazTestExecutionListener.class
|
||||||
})
|
})
|
||||||
static class MetaWithOverridesTestCase {
|
static class MetaWithOverridesTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@MetaInheritedListenersWithOverrides(listeners = { FooTestExecutionListener.class, BarTestExecutionListener.class })
|
@MetaInheritedListenersWithOverrides(listeners = {FooTestExecutionListener.class, BarTestExecutionListener.class})
|
||||||
static class MetaInheritedListenersWithOverridesTestCase extends MetaWithOverridesTestCase {
|
static class MetaInheritedListenersWithOverridesTestCase extends MetaWithOverridesTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@MetaNonInheritedListenersWithOverrides(listeners = {//
|
@MetaNonInheritedListenersWithOverrides(listeners = {
|
||||||
FooTestExecutionListener.class,//
|
FooTestExecutionListener.class,
|
||||||
BarTestExecutionListener.class,//
|
BarTestExecutionListener.class,
|
||||||
BazTestExecutionListener.class //
|
BazTestExecutionListener.class
|
||||||
},//
|
}, inheritListeners = true)
|
||||||
inheritListeners = true)
|
|
||||||
static class MetaNonInheritedListenersWithOverridesTestCase extends MetaInheritedListenersWithOverridesTestCase {
|
static class MetaNonInheritedListenersWithOverridesTestCase extends MetaInheritedListenersWithOverridesTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,4 +342,4 @@ public class TestExecutionListenersTests {
|
|||||||
static class EnigmaTestExecutionListener extends AbstractTestExecutionListener {
|
static class EnigmaTestExecutionListener extends AbstractTestExecutionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user