Convert TestContext to interface & default impl
Since the Spring TestContext Framework was introduced in Spring Framework 2.5, the TestContext class has always been a public class with package private constructors. The visibility of TestContext's constructor and methods was intentionally limited in order to hide the implementation details of the context cache, etc. However, this fact has made it difficult (if not impossible) to unit test custom TestExecutionListener implementations. This commit addresses this issue by converting TestContext into a public interface with a package private DefaultTestContext implementation. This enables unit testing of any components that depend on a TestContext (e.g., TestExecutionListeners) while at the same time preserving the encapsulation of the inner workings of the TestContext implementation with regard to context loading and caching. Issue: SPR-7692
This commit is contained in:
parent
2e1c035d42
commit
88fe2e9b00
|
@ -0,0 +1,183 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2013 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.test.context;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.core.AttributeAccessorSupport;
|
||||||
|
import org.springframework.core.style.ToStringCreator;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext.HierarchyMode;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of the {@link TestContext} interface.
|
||||||
|
*
|
||||||
|
* <p>Although {@code DefaultTestContext} was first introduced in Spring Framework
|
||||||
|
* 4.0, the initial implementation of this class was extracted from the existing
|
||||||
|
* code base for {@code TestContext} when {@code TestContext} was converted into
|
||||||
|
* an interface.
|
||||||
|
*
|
||||||
|
* @author Sam Brannen
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
class DefaultTestContext extends AttributeAccessorSupport implements TestContext {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -5827157174866681233L;
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(DefaultTestContext.class);
|
||||||
|
|
||||||
|
private final ContextCache contextCache;
|
||||||
|
|
||||||
|
private final CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate;
|
||||||
|
|
||||||
|
private final MergedContextConfiguration mergedContextConfiguration;
|
||||||
|
|
||||||
|
private final Class<?> testClass;
|
||||||
|
|
||||||
|
private Object testInstance;
|
||||||
|
|
||||||
|
private Method testMethod;
|
||||||
|
|
||||||
|
private Throwable testException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates to {@link #DefaultTestContext(Class, ContextCache, String)} with a
|
||||||
|
* value of {@code null} for the default {@code ContextLoader} class name.
|
||||||
|
*/
|
||||||
|
DefaultTestContext(Class<?> testClass, ContextCache contextCache) {
|
||||||
|
this(testClass, contextCache, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new test context for the supplied {@linkplain Class test class}
|
||||||
|
* and {@linkplain ContextCache context cache} and parse the corresponding
|
||||||
|
* {@link ContextConfiguration @ContextConfiguration} or
|
||||||
|
* {@link ContextHierarchy @ContextHierarchy} annotation, if present.
|
||||||
|
* <p>If the supplied class name for the default {@code ContextLoader}
|
||||||
|
* is {@code null} or <em>empty</em> and no concrete {@code ContextLoader}
|
||||||
|
* class is explicitly supplied via {@code @ContextConfiguration}, a
|
||||||
|
* {@link org.springframework.test.context.support.DelegatingSmartContextLoader
|
||||||
|
* DelegatingSmartContextLoader} or
|
||||||
|
* {@link org.springframework.test.context.web.WebDelegatingSmartContextLoader
|
||||||
|
* WebDelegatingSmartContextLoader} will be used instead.
|
||||||
|
* @param testClass the test class for which the test context should be
|
||||||
|
* constructed (must not be {@code null})
|
||||||
|
* @param contextCache the context cache from which the constructed test
|
||||||
|
* context should retrieve application contexts (must not be
|
||||||
|
* {@code null})
|
||||||
|
* @param defaultContextLoaderClassName the name of the default
|
||||||
|
* {@code ContextLoader} class to use (may be {@code null})
|
||||||
|
*/
|
||||||
|
DefaultTestContext(Class<?> testClass, ContextCache contextCache, String defaultContextLoaderClassName) {
|
||||||
|
Assert.notNull(testClass, "Test class must not be null");
|
||||||
|
Assert.notNull(contextCache, "ContextCache must not be null");
|
||||||
|
|
||||||
|
this.testClass = testClass;
|
||||||
|
this.contextCache = contextCache;
|
||||||
|
this.cacheAwareContextLoaderDelegate = new CacheAwareContextLoaderDelegate(contextCache);
|
||||||
|
|
||||||
|
MergedContextConfiguration mergedContextConfiguration;
|
||||||
|
|
||||||
|
if (testClass.isAnnotationPresent(ContextConfiguration.class)
|
||||||
|
|| testClass.isAnnotationPresent(ContextHierarchy.class)) {
|
||||||
|
mergedContextConfiguration = ContextLoaderUtils.buildMergedContextConfiguration(testClass,
|
||||||
|
defaultContextLoaderClassName, cacheAwareContextLoaderDelegate);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info(String.format(
|
||||||
|
"Neither @ContextConfiguration nor @ContextHierarchy found for test class [%s]",
|
||||||
|
testClass.getName()));
|
||||||
|
}
|
||||||
|
mergedContextConfiguration = new MergedContextConfiguration(testClass, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mergedContextConfiguration = mergedContextConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public ApplicationContext getApplicationContext() {
|
||||||
|
return cacheAwareContextLoaderDelegate.loadContext(mergedContextConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public final Class<?> getTestClass() {
|
||||||
|
return testClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public final Object getTestInstance() {
|
||||||
|
return testInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public final Method getTestMethod() {
|
||||||
|
return testMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public final Throwable getTestException() {
|
||||||
|
return testException;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void markApplicationContextDirty(HierarchyMode hierarchyMode) {
|
||||||
|
contextCache.remove(mergedContextConfiguration, hierarchyMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void updateState(Object testInstance, Method testMethod, Throwable testException) {
|
||||||
|
this.testInstance = testInstance;
|
||||||
|
this.testMethod = testMethod;
|
||||||
|
this.testException = testException;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide a String representation of this test context's state.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringCreator(this)//
|
||||||
|
.append("testClass", testClass)//
|
||||||
|
.append("testInstance", testInstance)//
|
||||||
|
.append("testMethod", testMethod)//
|
||||||
|
.append("testException", testException)//
|
||||||
|
.append("mergedContextConfiguration", mergedContextConfiguration)//
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,119 +16,40 @@
|
||||||
|
|
||||||
package org.springframework.test.context;
|
package org.springframework.test.context;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.core.AttributeAccessorSupport;
|
import org.springframework.core.AttributeAccessor;
|
||||||
import org.springframework.core.style.ToStringCreator;
|
|
||||||
import org.springframework.test.annotation.DirtiesContext.HierarchyMode;
|
import org.springframework.test.annotation.DirtiesContext.HierarchyMode;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code TestContext} encapsulates the context in which a test is executed,
|
* {@code TestContext} encapsulates the context in which a test is executed,
|
||||||
* agnostic of the actual testing framework in use.
|
* agnostic of the actual testing framework in use.
|
||||||
*
|
*
|
||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
* @author Juergen Hoeller
|
|
||||||
* @since 2.5
|
* @since 2.5
|
||||||
*/
|
*/
|
||||||
public class TestContext extends AttributeAccessorSupport {
|
public interface TestContext extends AttributeAccessor, Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -5827157174866681233L;
|
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(TestContext.class);
|
|
||||||
|
|
||||||
private final ContextCache contextCache;
|
|
||||||
|
|
||||||
private final CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate;
|
|
||||||
|
|
||||||
private final MergedContextConfiguration mergedContextConfiguration;
|
|
||||||
|
|
||||||
private final Class<?> testClass;
|
|
||||||
|
|
||||||
private Object testInstance;
|
|
||||||
|
|
||||||
private Method testMethod;
|
|
||||||
|
|
||||||
private Throwable testException;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delegates to {@link #TestContext(Class, ContextCache, String)} with a
|
|
||||||
* value of {@code null} for the default {@code ContextLoader} class name.
|
|
||||||
*/
|
|
||||||
TestContext(Class<?> testClass, ContextCache contextCache) {
|
|
||||||
this(testClass, contextCache, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new test context for the supplied {@linkplain Class test class}
|
|
||||||
* and {@linkplain ContextCache context cache} and parse the corresponding
|
|
||||||
* {@link ContextConfiguration @ContextConfiguration} or
|
|
||||||
* {@link ContextHierarchy @ContextHierarchy} annotation, if present.
|
|
||||||
* <p>If the supplied class name for the default {@code ContextLoader}
|
|
||||||
* is {@code null} or <em>empty</em> and no concrete {@code ContextLoader}
|
|
||||||
* class is explicitly supplied via {@code @ContextConfiguration}, a
|
|
||||||
* {@link org.springframework.test.context.support.DelegatingSmartContextLoader
|
|
||||||
* DelegatingSmartContextLoader} or
|
|
||||||
* {@link org.springframework.test.context.web.WebDelegatingSmartContextLoader
|
|
||||||
* WebDelegatingSmartContextLoader} will be used instead.
|
|
||||||
* @param testClass the test class for which the test context should be
|
|
||||||
* constructed (must not be {@code null})
|
|
||||||
* @param contextCache the context cache from which the constructed test
|
|
||||||
* context should retrieve application contexts (must not be
|
|
||||||
* {@code null})
|
|
||||||
* @param defaultContextLoaderClassName the name of the default
|
|
||||||
* {@code ContextLoader} class to use (may be {@code null})
|
|
||||||
*/
|
|
||||||
TestContext(Class<?> testClass, ContextCache contextCache, String defaultContextLoaderClassName) {
|
|
||||||
Assert.notNull(testClass, "Test class must not be null");
|
|
||||||
Assert.notNull(contextCache, "ContextCache must not be null");
|
|
||||||
|
|
||||||
this.testClass = testClass;
|
|
||||||
this.contextCache = contextCache;
|
|
||||||
this.cacheAwareContextLoaderDelegate = new CacheAwareContextLoaderDelegate(contextCache);
|
|
||||||
|
|
||||||
MergedContextConfiguration mergedContextConfiguration;
|
|
||||||
|
|
||||||
if (testClass.isAnnotationPresent(ContextConfiguration.class)
|
|
||||||
|| testClass.isAnnotationPresent(ContextHierarchy.class)) {
|
|
||||||
mergedContextConfiguration = ContextLoaderUtils.buildMergedContextConfiguration(testClass,
|
|
||||||
defaultContextLoaderClassName, cacheAwareContextLoaderDelegate);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (logger.isInfoEnabled()) {
|
|
||||||
logger.info(String.format(
|
|
||||||
"Neither @ContextConfiguration nor @ContextHierarchy found for test class [%s]",
|
|
||||||
testClass.getName()));
|
|
||||||
}
|
|
||||||
mergedContextConfiguration = new MergedContextConfiguration(testClass, null, null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mergedContextConfiguration = mergedContextConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link ApplicationContext application context} for this test
|
* Get the {@link ApplicationContext application context} for this test
|
||||||
* context, possibly cached.
|
* context, possibly cached.
|
||||||
|
*
|
||||||
|
* <p>Implementations of this method are responsible for loading the
|
||||||
|
* application context if the corresponding context has not already been
|
||||||
|
* loaded, potentially caching the context as well.
|
||||||
* @return the application context
|
* @return the application context
|
||||||
* @throws IllegalStateException if an error occurs while retrieving the
|
* @throws IllegalStateException if an error occurs while retrieving the
|
||||||
* application context
|
* application context
|
||||||
*/
|
*/
|
||||||
public ApplicationContext getApplicationContext() {
|
ApplicationContext getApplicationContext();
|
||||||
return cacheAwareContextLoaderDelegate.loadContext(mergedContextConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link Class test class} for this test context.
|
* Get the {@link Class test class} for this test context.
|
||||||
* @return the test class (never {@code null})
|
* @return the test class (never {@code null})
|
||||||
*/
|
*/
|
||||||
public final Class<?> getTestClass() {
|
Class<?> getTestClass();
|
||||||
return testClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current {@link Object test instance} for this test context.
|
* Get the current {@link Object test instance} for this test context.
|
||||||
|
@ -136,9 +57,7 @@ public class TestContext extends AttributeAccessorSupport {
|
||||||
* @return the current test instance (may be {@code null})
|
* @return the current test instance (may be {@code null})
|
||||||
* @see #updateState(Object, Method, Throwable)
|
* @see #updateState(Object, Method, Throwable)
|
||||||
*/
|
*/
|
||||||
public final Object getTestInstance() {
|
Object getTestInstance();
|
||||||
return testInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current {@link Method test method} for this test context.
|
* Get the current {@link Method test method} for this test context.
|
||||||
|
@ -146,9 +65,7 @@ public class TestContext extends AttributeAccessorSupport {
|
||||||
* @return the current test method (may be {@code null})
|
* @return the current test method (may be {@code null})
|
||||||
* @see #updateState(Object, Method, Throwable)
|
* @see #updateState(Object, Method, Throwable)
|
||||||
*/
|
*/
|
||||||
public final Method getTestMethod() {
|
Method getTestMethod();
|
||||||
return testMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the {@link Throwable exception} that was thrown during execution of
|
* Get the {@link Throwable exception} that was thrown during execution of
|
||||||
|
@ -158,22 +75,7 @@ public class TestContext extends AttributeAccessorSupport {
|
||||||
* exception was thrown
|
* exception was thrown
|
||||||
* @see #updateState(Object, Method, Throwable)
|
* @see #updateState(Object, Method, Throwable)
|
||||||
*/
|
*/
|
||||||
public final Throwable getTestException() {
|
Throwable getTestException();
|
||||||
return testException;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call this method to signal that the {@linkplain ApplicationContext application
|
|
||||||
* context} associated with this test context is <em>dirty</em> and should be
|
|
||||||
* discarded. Do this if a test has modified the context — for example,
|
|
||||||
* by replacing a bean definition or modifying the state of a singleton bean.
|
|
||||||
* @deprecated as of Spring 3.2.2; use
|
|
||||||
* {@link #markApplicationContextDirty(DirtiesContext.HierarchyMode)} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void markApplicationContextDirty() {
|
|
||||||
markApplicationContextDirty((HierarchyMode) null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this method to signal that the {@linkplain ApplicationContext application
|
* Call this method to signal that the {@linkplain ApplicationContext application
|
||||||
|
@ -183,36 +85,18 @@ public class TestContext extends AttributeAccessorSupport {
|
||||||
* @param hierarchyMode the context cache clearing mode to be applied if the
|
* @param hierarchyMode the context cache clearing mode to be applied if the
|
||||||
* context is part of a hierarchy (may be {@code null})
|
* context is part of a hierarchy (may be {@code null})
|
||||||
*/
|
*/
|
||||||
public void markApplicationContextDirty(HierarchyMode hierarchyMode) {
|
void markApplicationContextDirty(HierarchyMode hierarchyMode);
|
||||||
contextCache.remove(mergedContextConfiguration, hierarchyMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update this test context to reflect the state of the currently executing
|
* Update this test context to reflect the state of the currently executing
|
||||||
* test.
|
* test.
|
||||||
|
* <p>Caution: concurrent invocations of this method might not be thread-safe,
|
||||||
|
* depending on the underlying implementation.
|
||||||
* @param testInstance the current test instance (may be {@code null})
|
* @param testInstance the current test instance (may be {@code null})
|
||||||
* @param testMethod the current test method (may be {@code null})
|
* @param testMethod the current test method (may be {@code null})
|
||||||
* @param testException the exception that was thrown in the test method, or
|
* @param testException the exception that was thrown in the test method, or
|
||||||
* {@code null} if no exception was thrown
|
* {@code null} if no exception was thrown
|
||||||
*/
|
*/
|
||||||
void updateState(Object testInstance, Method testMethod, Throwable testException) {
|
void updateState(Object testInstance, Method testMethod, Throwable testException);
|
||||||
this.testInstance = testInstance;
|
|
||||||
this.testMethod = testMethod;
|
|
||||||
this.testException = testException;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide a String representation of this test context's state.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return new ToStringCreator(this)//
|
|
||||||
.append("testClass", testClass)//
|
|
||||||
.append("testInstance", testInstance)//
|
|
||||||
.append("testMethod", testMethod)//
|
|
||||||
.append("testException", testException)//
|
|
||||||
.append("mergedContextConfiguration", mergedContextConfiguration)//
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 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.
|
||||||
|
@ -26,7 +26,6 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
@ -114,7 +113,7 @@ public class TestContextManager {
|
||||||
* @see #registerTestExecutionListeners(TestExecutionListener...)
|
* @see #registerTestExecutionListeners(TestExecutionListener...)
|
||||||
*/
|
*/
|
||||||
public TestContextManager(Class<?> testClass, String defaultContextLoaderClassName) {
|
public TestContextManager(Class<?> testClass, String defaultContextLoaderClassName) {
|
||||||
this.testContext = new TestContext(testClass, contextCache, defaultContextLoaderClassName);
|
this.testContext = new DefaultTestContext(testClass, contextCache, defaultContextLoaderClassName);
|
||||||
registerTestExecutionListeners(retrieveTestExecutionListeners(testClass));
|
registerTestExecutionListeners(retrieveTestExecutionListeners(testClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,7 +184,8 @@ public class TestContextManager {
|
||||||
}
|
}
|
||||||
classesList.addAll(getDefaultTestExecutionListenerClasses());
|
classesList.addAll(getDefaultTestExecutionListenerClasses());
|
||||||
defaultListeners = true;
|
defaultListeners = true;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// Traverse the class hierarchy...
|
// Traverse the class hierarchy...
|
||||||
while (declaringClass != null) {
|
while (declaringClass != null) {
|
||||||
TestExecutionListeners testExecutionListeners = declaringClass.getAnnotation(annotationType);
|
TestExecutionListeners testExecutionListeners = declaringClass.getAnnotation(annotationType);
|
||||||
|
@ -204,7 +204,8 @@ public class TestContextManager {
|
||||||
ObjectUtils.nullSafeToString(listenerClasses));
|
ObjectUtils.nullSafeToString(listenerClasses));
|
||||||
logger.error(msg);
|
logger.error(msg);
|
||||||
throw new IllegalStateException(msg);
|
throw new IllegalStateException(msg);
|
||||||
} else if (!ObjectUtils.isEmpty(valueListenerClasses)) {
|
}
|
||||||
|
else if (!ObjectUtils.isEmpty(valueListenerClasses)) {
|
||||||
listenerClasses = valueListenerClasses;
|
listenerClasses = valueListenerClasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,14 +221,16 @@ public class TestContextManager {
|
||||||
for (Class<? extends TestExecutionListener> listenerClass : classesList) {
|
for (Class<? extends TestExecutionListener> listenerClass : classesList) {
|
||||||
try {
|
try {
|
||||||
listeners.add(BeanUtils.instantiateClass(listenerClass));
|
listeners.add(BeanUtils.instantiateClass(listenerClass));
|
||||||
} catch (NoClassDefFoundError err) {
|
}
|
||||||
|
catch (NoClassDefFoundError err) {
|
||||||
if (defaultListeners) {
|
if (defaultListeners) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Could not instantiate default TestExecutionListener class ["
|
logger.debug("Could not instantiate default TestExecutionListener class ["
|
||||||
+ listenerClass.getName()
|
+ listenerClass.getName()
|
||||||
+ "]. Specify custom listener classes or make the default listener classes available.");
|
+ "]. Specify custom listener classes or make the default listener classes available.");
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,7 +248,8 @@ public class TestContextManager {
|
||||||
try {
|
try {
|
||||||
defaultListenerClasses.add((Class<? extends TestExecutionListener>) getClass().getClassLoader().loadClass(
|
defaultListenerClasses.add((Class<? extends TestExecutionListener>) getClass().getClassLoader().loadClass(
|
||||||
className));
|
className));
|
||||||
} catch (Throwable t) {
|
}
|
||||||
|
catch (Throwable t) {
|
||||||
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.", t);
|
+ "]. Specify custom listener classes or make the default listener classes available.", t);
|
||||||
|
@ -278,7 +282,8 @@ public class TestContextManager {
|
||||||
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
|
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
|
||||||
try {
|
try {
|
||||||
testExecutionListener.beforeTestClass(getTestContext());
|
testExecutionListener.beforeTestClass(getTestContext());
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
|
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
|
||||||
+ "] to process 'before class' callback for test class [" + testClass + "]", ex);
|
+ "] to process 'before class' callback for test class [" + testClass + "]", ex);
|
||||||
throw ex;
|
throw ex;
|
||||||
|
@ -310,7 +315,8 @@ public class TestContextManager {
|
||||||
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
|
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
|
||||||
try {
|
try {
|
||||||
testExecutionListener.prepareTestInstance(getTestContext());
|
testExecutionListener.prepareTestInstance(getTestContext());
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
logger.error("Caught exception while allowing TestExecutionListener [" + testExecutionListener
|
logger.error("Caught exception while allowing TestExecutionListener [" + testExecutionListener
|
||||||
+ "] to prepare test instance [" + testInstance + "]", ex);
|
+ "] to prepare test instance [" + testInstance + "]", ex);
|
||||||
throw ex;
|
throw ex;
|
||||||
|
@ -346,7 +352,8 @@ public class TestContextManager {
|
||||||
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
|
for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) {
|
||||||
try {
|
try {
|
||||||
testExecutionListener.beforeTestMethod(getTestContext());
|
testExecutionListener.beforeTestMethod(getTestContext());
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
|
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
|
||||||
+ "] to process 'before' execution of test method [" + testMethod + "] for test instance ["
|
+ "] to process 'before' execution of test method [" + testMethod + "] for test instance ["
|
||||||
+ testInstance + "]", ex);
|
+ testInstance + "]", ex);
|
||||||
|
@ -393,7 +400,8 @@ public class TestContextManager {
|
||||||
for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) {
|
for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) {
|
||||||
try {
|
try {
|
||||||
testExecutionListener.afterTestMethod(getTestContext());
|
testExecutionListener.afterTestMethod(getTestContext());
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
|
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
|
||||||
+ "] to process 'after' execution for test: method [" + testMethod + "], instance ["
|
+ "] to process 'after' execution for test: method [" + testMethod + "], instance ["
|
||||||
+ testInstance + "], exception [" + exception + "]", ex);
|
+ testInstance + "], exception [" + exception + "]", ex);
|
||||||
|
@ -434,7 +442,8 @@ public class TestContextManager {
|
||||||
for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) {
|
for (TestExecutionListener testExecutionListener : getReversedTestExecutionListeners()) {
|
||||||
try {
|
try {
|
||||||
testExecutionListener.afterTestClass(getTestContext());
|
testExecutionListener.afterTestClass(getTestContext());
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
|
logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener
|
||||||
+ "] to process 'after class' callback for test class [" + testClass + "]", ex);
|
+ "] to process 'after class' callback for test class [" + testClass + "]", ex);
|
||||||
if (afterTestClassException == null) {
|
if (afterTestClassException == null) {
|
||||||
|
|
|
@ -44,22 +44,6 @@ public class DirtiesContextTestExecutionListener extends AbstractTestExecutionLi
|
||||||
private static final Log logger = LogFactory.getLog(DirtiesContextTestExecutionListener.class);
|
private static final Log logger = LogFactory.getLog(DirtiesContextTestExecutionListener.class);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks the {@linkplain ApplicationContext application context} of the supplied
|
|
||||||
* {@linkplain TestContext test context} as
|
|
||||||
* {@linkplain TestContext#markApplicationContextDirty() dirty}, and sets the
|
|
||||||
* {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE}
|
|
||||||
* in the test context to {@code true}.
|
|
||||||
* @param testContext the test context whose application context should
|
|
||||||
* marked as dirty
|
|
||||||
* @deprecated as of Spring 3.2.2, use {@link #dirtyContext(TestContext, HierarchyMode)} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
protected void dirtyContext(TestContext testContext) {
|
|
||||||
testContext.markApplicationContextDirty();
|
|
||||||
testContext.setAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE, Boolean.TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the {@linkplain ApplicationContext application context} of the supplied
|
* Marks the {@linkplain ApplicationContext application context} of the supplied
|
||||||
* {@linkplain TestContext test context} as
|
* {@linkplain TestContext test context} as
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class ContextCacheTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApplicationContext loadContext(Class<?> testClass) {
|
private ApplicationContext loadContext(Class<?> testClass) {
|
||||||
TestContext testContext = new TestContext(testClass, contextCache);
|
TestContext testContext = new DefaultTestContext(testClass, contextCache);
|
||||||
return testContext.getApplicationContext();
|
return testContext.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,13 +119,15 @@ public class ContextCacheTests {
|
||||||
public void removeContextHierarchyCacheLevel1() {
|
public void removeContextHierarchyCacheLevel1() {
|
||||||
|
|
||||||
// Load Level 3-A
|
// Load Level 3-A
|
||||||
TestContext testContext3a = new TestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache);
|
TestContext testContext3a = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3a.getApplicationContext();
|
testContext3a.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
|
||||||
// Load Level 3-B
|
// Load Level 3-B
|
||||||
TestContext testContext3b = new TestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache);
|
TestContext testContext3b = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3b.getApplicationContext();
|
testContext3b.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
@ -142,13 +144,15 @@ public class ContextCacheTests {
|
||||||
public void removeContextHierarchyCacheLevel1WithExhaustiveMode() {
|
public void removeContextHierarchyCacheLevel1WithExhaustiveMode() {
|
||||||
|
|
||||||
// Load Level 3-A
|
// Load Level 3-A
|
||||||
TestContext testContext3a = new TestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache);
|
TestContext testContext3a = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3a.getApplicationContext();
|
testContext3a.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
|
||||||
// Load Level 3-B
|
// Load Level 3-B
|
||||||
TestContext testContext3b = new TestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache);
|
TestContext testContext3b = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3b.getApplicationContext();
|
testContext3b.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
@ -165,13 +169,15 @@ public class ContextCacheTests {
|
||||||
public void removeContextHierarchyCacheLevel2() {
|
public void removeContextHierarchyCacheLevel2() {
|
||||||
|
|
||||||
// Load Level 3-A
|
// Load Level 3-A
|
||||||
TestContext testContext3a = new TestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache);
|
TestContext testContext3a = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3a.getApplicationContext();
|
testContext3a.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
|
||||||
// Load Level 3-B
|
// Load Level 3-B
|
||||||
TestContext testContext3b = new TestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache);
|
TestContext testContext3b = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3b.getApplicationContext();
|
testContext3b.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
@ -189,13 +195,15 @@ public class ContextCacheTests {
|
||||||
public void removeContextHierarchyCacheLevel2WithExhaustiveMode() {
|
public void removeContextHierarchyCacheLevel2WithExhaustiveMode() {
|
||||||
|
|
||||||
// Load Level 3-A
|
// Load Level 3-A
|
||||||
TestContext testContext3a = new TestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache);
|
TestContext testContext3a = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3a.getApplicationContext();
|
testContext3a.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
|
||||||
// Load Level 3-B
|
// Load Level 3-B
|
||||||
TestContext testContext3b = new TestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache);
|
TestContext testContext3b = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3b.getApplicationContext();
|
testContext3b.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
@ -211,13 +219,15 @@ public class ContextCacheTests {
|
||||||
public void removeContextHierarchyCacheLevel3Then2() {
|
public void removeContextHierarchyCacheLevel3Then2() {
|
||||||
|
|
||||||
// Load Level 3-A
|
// Load Level 3-A
|
||||||
TestContext testContext3a = new TestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache);
|
TestContext testContext3a = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3a.getApplicationContext();
|
testContext3a.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
|
||||||
// Load Level 3-B
|
// Load Level 3-B
|
||||||
TestContext testContext3b = new TestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache);
|
TestContext testContext3b = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3b.getApplicationContext();
|
testContext3b.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
@ -238,13 +248,15 @@ public class ContextCacheTests {
|
||||||
public void removeContextHierarchyCacheLevel3Then2WithExhaustiveMode() {
|
public void removeContextHierarchyCacheLevel3Then2WithExhaustiveMode() {
|
||||||
|
|
||||||
// Load Level 3-A
|
// Load Level 3-A
|
||||||
TestContext testContext3a = new TestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class, contextCache);
|
TestContext testContext3a = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3aTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3a.getApplicationContext();
|
testContext3a.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
assertContextCacheStatistics(contextCache, "level 3, A", 3, 0, 3);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
|
||||||
// Load Level 3-B
|
// Load Level 3-B
|
||||||
TestContext testContext3b = new TestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class, contextCache);
|
TestContext testContext3b = new DefaultTestContext(ClassHierarchyContextHierarchyLevel3bTestCase.class,
|
||||||
|
contextCache);
|
||||||
testContext3b.getApplicationContext();
|
testContext3b.getApplicationContext();
|
||||||
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
assertContextCacheStatistics(contextCache, "level 3, A and B", 4, 1, 4);
|
||||||
assertParentContextCount(2);
|
assertParentContextCount(2);
|
||||||
|
|
Loading…
Reference in New Issue