diff --git a/org.springframework.test/src/main/java/org/springframework/test/annotation/DirtiesContext.java b/org.springframework.test/src/main/java/org/springframework/test/annotation/DirtiesContext.java index b22ff81782..5c8a66cb23 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/annotation/DirtiesContext.java +++ b/org.springframework.test/src/main/java/org/springframework/test/annotation/DirtiesContext.java @@ -23,14 +23,30 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Test annotation to indicate that a test method dirties the context - * for the current test. - * + * Test annotation which indicates that the + * {@link org.springframework.context.ApplicationContext ApplicationContext} + * associated with a test is dirty and should be closed: + *
+ * Use this annotation if a test has modified the context (for example, by + * replacing a bean definition). Subsequent tests will be supplied a new + * context. + *
+ *
+ * @DirtiesContext may be used as a class-level and
+ * method-level annotation within the same class. In such scenarios, the
+ * ApplicationContext will be marked as dirty after any
+ * such annotated method as well as after the entire class.
+ *
+ * An attempt will be made to give each registered + * {@link TestExecutionListener} a chance to pre-process the test class + * execution. If a listener throws an exception, however, the remaining + * registered listeners will not be called. + * + * @throws Exception if a registered TestExecutionListener throws an + * exception + * @see #getTestExecutionListeners() + */ + public void beforeTestClass() throws Exception { + final Class> testClass = getTestContext().getTestClass(); + if (logger.isTraceEnabled()) { + logger.trace("beforeTestClass(): class [" + testClass + "]"); + } + + for (TestExecutionListener testExecutionListener : getTestExecutionListeners()) { + try { + testExecutionListener.beforeTestClass(getTestContext()); + } + catch (Exception ex) { + logger.warn("Caught exception while allowing TestExecutionListener [" + testExecutionListener + + "] to process 'before class' callback for test class [" + testClass + "]", ex); + throw ex; + } + } + } + /** * Hook for preparing a test instance prior to execution of any individual * test methods, for example for injecting dependencies, etc. Should be @@ -279,7 +312,7 @@ public class TestContextManager { * {@link Method test method}, for example for setting up test fixtures, * starting a transaction, etc. Should be called prior to any * framework-specific before methods (e.g., methods annotated with - * JUnit's {@link org.junit.Before @Before} ). + * JUnit's {@link org.junit.Before @Before}). *
* The managed {@link TestContext} will be updated with the supplied
* testInstance and testMethod.
@@ -377,4 +410,51 @@ public class TestContextManager {
}
}
+ /**
+ * Hook for post-processing a test class after execution of all
+ * tests within the class. Should be called after any framework-specific
+ * after class methods (e.g., methods annotated with JUnit's
+ * {@link org.junit.AfterClass @AfterClass}).
+ *
+ * Each registered {@link TestExecutionListener} will be given a chance to
+ * post-process the test class. If a listener throws an exception, the
+ * remaining registered listeners will still be called, but the first
+ * exception thrown will be tracked and rethrown after all listeners have
+ * executed. Note that registered listeners will be executed in the opposite
+ * order in which they were registered.
+ *
+ * @throws Exception if a registered TestExecutionListener throws an
+ * exception
+ * @see #getTestExecutionListeners()
+ */
+ public void afterTestClass() throws Exception {
+ final Class> testClass = getTestContext().getTestClass();
+ if (logger.isTraceEnabled()) {
+ logger.trace("afterTestClass(): class [" + testClass + "]");
+ }
+
+ // Traverse the TestExecutionListeners in reverse order to ensure proper
+ // "wrapper"-style execution of listeners.
+ List
+ * This method should be called immediately before framework-specific
+ * before class lifecycle callbacks.
+ *
+ * @param testContext the test context for the test; never null
+ * @throws Exception allows any exception to propagate
+ */
+ void beforeTestClass(TestContext testContext) throws Exception;
+
/**
* Prepares the {@link Object test instance} of the supplied
- * {@link TestContext test context}, for example by injecting
- * dependencies.
- *
This method should be called immediately after instantiation
- * of the test instance but prior to any framework-specific lifecycle
- * callbacks.
- * @param testContext the test context for the test (never null)
+ * {@link TestContext test context}, for example by injecting dependencies.
+ *
+ * This method should be called immediately after instantiation of the test
+ * instance but prior to any framework-specific lifecycle callbacks.
+ *
+ * @param testContext the test context for the test; never null
* @throws Exception allows any exception to propagate
*/
void prepareTestInstance(TestContext testContext) throws Exception;
@@ -59,10 +77,12 @@ public interface TestExecutionListener {
* {@link java.lang.reflect.Method test method} in the supplied
* {@link TestContext test context}, for example by setting up test
* fixtures.
- *
This method should be called immediately prior to any - * framework-specific before lifecycle callbacks. + *
+ * This method should be called immediately prior to framework-specific
+ * before lifecycle callbacks.
+ *
* @param testContext the test context in which the test method will be
- * executed (never null)
+ * executed; never null
* @throws Exception allows any exception to propagate
*/
void beforeTestMethod(TestContext testContext) throws Exception;
@@ -72,12 +92,26 @@ public interface TestExecutionListener {
* {@link java.lang.reflect.Method test method} in the supplied
* {@link TestContext test context}, for example by tearing down test
* fixtures.
- *
This method should be called immediately after any - * framework-specific after lifecycle callbacks. + *
+ * This method should be called immediately after framework-specific
+ * after lifecycle callbacks.
+ *
* @param testContext the test context in which the test method was
- * executed (never null)
+ * executed; never null
* @throws Exception allows any exception to propagate
*/
void afterTestMethod(TestContext testContext) throws Exception;
+ /**
+ * Post-processes a test class after execution of all tests within
+ * the class.
+ *
+ * This method should be called immediately after framework-specific
+ * after class lifecycle callbacks.
+ *
+ * @param testContext the test context for the test; never
@@ -47,19 +48,19 @@ import org.springframework.test.context.support.DirtiesContextTestExecutionListe
* Concrete subclasses:
* null
+ * @throws Exception allows any exception to propagate
+ */
+ void afterTestClass(TestContext testContext) throws Exception;
+
}
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java
index 732122edb1..f9588c65f5 100644
--- a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/SpringJUnit4ClassRunner.java
@@ -39,8 +39,10 @@ import org.springframework.test.annotation.ProfileValueUtils;
import org.springframework.test.annotation.Repeat;
import org.springframework.test.annotation.Timed;
import org.springframework.test.context.TestContextManager;
-import org.springframework.test.context.junit4.statements.RunSpringTestContextAfters;
-import org.springframework.test.context.junit4.statements.RunSpringTestContextBefores;
+import org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks;
+import org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks;
+import org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks;
+import org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks;
import org.springframework.test.context.junit4.statements.SpringFailOnTimeout;
import org.springframework.test.context.junit4.statements.SpringRepeat;
@@ -142,20 +144,6 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
return null;
}
- /**
- * Delegates to the parent implementation for creating the test instance and
- * then allows the {@link #getTestContextManager() TestContextManager} to
- * prepare the test instance before returning it.
- *
- * @see TestContextManager#prepareTestInstance(Object)
- */
- @Override
- protected Object createTest() throws Exception {
- Object testInstance = super.createTest();
- getTestContextManager().prepareTestInstance(testInstance);
- return testInstance;
- }
-
/**
* Returns a description suitable for an ignored test class if the test is
* disabled via @IfProfileValue at the class-level, and
@@ -191,6 +179,47 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
super.run(notifier);
}
+ /**
+ * Wraps the {@link Statement} returned by the parent implementation with a
+ * {@link RunBeforeTestClassCallbacks} statement, thus preserving the
+ * default functionality but adding support for the Spring TestContext
+ * Framework.
+ *
+ * @see RunBeforeTestClassCallbacks
+ */
+ @Override
+ protected Statement withBeforeClasses(Statement statement) {
+ Statement junitBeforeClasses = super.withBeforeClasses(statement);
+ return new RunBeforeTestClassCallbacks(junitBeforeClasses, getTestContextManager());
+ }
+
+ /**
+ * Wraps the {@link Statement} returned by the parent implementation with a
+ * {@link RunAfterTestClassCallbacks} statement, thus preserving the default
+ * functionality but adding support for the Spring TestContext Framework.
+ *
+ * @see RunAfterTestClassCallbacks
+ */
+ @Override
+ protected Statement withAfterClasses(Statement statement) {
+ Statement junitAfterClasses = super.withAfterClasses(statement);
+ return new RunAfterTestClassCallbacks(junitAfterClasses, getTestContextManager());
+ }
+
+ /**
+ * Delegates to the parent implementation for creating the test instance and
+ * then allows the {@link #getTestContextManager() TestContextManager} to
+ * prepare the test instance before returning it.
+ *
+ * @see TestContextManager#prepareTestInstance(Object)
+ */
+ @Override
+ protected Object createTest() throws Exception {
+ Object testInstance = super.createTest();
+ getTestContextManager().prepareTestInstance(testInstance);
+ return testInstance;
+ }
+
/**
* Performs the same logic as
* {@link BlockJUnit4ClassRunner#runChild(FrameworkMethod, RunNotifier)},
@@ -393,30 +422,31 @@ public class SpringJUnit4ClassRunner extends BlockJUnit4ClassRunner {
/**
* Wraps the {@link Statement} returned by the parent implementation with a
- * {@link RunSpringTestContextBefores} statement, thus preserving the
+ * {@link RunBeforeTestMethodCallbacks} statement, thus preserving the
* default functionality but adding support for the Spring TestContext
* Framework.
*
- * @see RunSpringTestContextBefores
+ * @see RunBeforeTestMethodCallbacks
*/
@Override
protected Statement withBefores(FrameworkMethod frameworkMethod, Object testInstance, Statement statement) {
Statement junitBefores = super.withBefores(frameworkMethod, testInstance, statement);
- return new RunSpringTestContextBefores(junitBefores, testInstance, frameworkMethod.getMethod(),
+ return new RunBeforeTestMethodCallbacks(junitBefores, testInstance, frameworkMethod.getMethod(),
getTestContextManager());
}
/**
* Wraps the {@link Statement} returned by the parent implementation with a
- * {@link RunSpringTestContextAfters} statement, thus preserving the default
- * functionality but adding support for the Spring TestContext Framework.
+ * {@link RunAfterTestMethodCallbacks} statement, thus preserving the
+ * default functionality but adding support for the Spring TestContext
+ * Framework.
*
- * @see RunSpringTestContextAfters
+ * @see RunAfterTestMethodCallbacks
*/
@Override
protected Statement withAfters(FrameworkMethod frameworkMethod, Object testInstance, Statement statement) {
Statement junitAfters = super.withAfters(frameworkMethod, testInstance, statement);
- return new RunSpringTestContextAfters(junitAfters, testInstance, frameworkMethod.getMethod(),
+ return new RunAfterTestMethodCallbacks(junitAfters, testInstance, frameworkMethod.getMethod(),
getTestContextManager());
}
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunAfterTestClassCallbacks.java b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunAfterTestClassCallbacks.java
new file mode 100644
index 0000000000..0be5450c34
--- /dev/null
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunAfterTestClassCallbacks.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2002-2009 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.junit4.statements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.internal.runners.model.MultipleFailureException;
+import org.junit.runners.model.Statement;
+import org.springframework.test.context.TestContextManager;
+
+/**
+ * RunAfterTestClassCallbacks is a custom JUnit 4.5+
+ * {@link Statement} which allows the Spring TestContext Framework to
+ * be plugged into the JUnit execution chain by calling
+ * {@link TestContextManager#afterTestClass() afterTestClass()} on the supplied
+ * {@link TestContextManager}.
+ *
+ * @see #evaluate()
+ * @see RunBeforeTestMethodCallbacks
+ * @author Sam Brannen
+ * @since 3.0
+ */
+public class RunAfterTestClassCallbacks extends Statement {
+
+ private final Statement next;
+
+ private final TestContextManager testContextManager;
+
+
+ /**
+ * Constructs a new RunAfterTestClassCallbacks statement.
+ *
+ * @param next the next Statement in the execution chain
+ * @param testContextManager the TestContextManager upon which to call
+ * afterTestClass()
+ */
+ public RunAfterTestClassCallbacks(Statement next, TestContextManager testContextManager) {
+ this.next = next;
+ this.testContextManager = testContextManager;
+ }
+
+ /**
+ * Invokes the next {@link Statement} in the execution chain (typically an
+ * instance of {@link org.junit.internal.runners.statements.RunAfters
+ * RunAfters}), catching any exceptions thrown, and then calls
+ * {@link TestContextManager#afterTestClass()}. If the call to
+ * afterTestClass() throws an exception, it will also be
+ * tracked. Multiple exceptions will be combined into a
+ * {@link MultipleFailureException}.
+ */
+ @Override
+ public void evaluate() throws Throwable {
+ ListRunSpringTestContextAfters is a custom JUnit 4.5+
+ * RunAfterTestMethodCallbacks is a custom JUnit 4.5+
* {@link Statement} which allows the Spring TestContext Framework to
* be plugged into the JUnit execution chain by calling
* {@link TestContextManager#afterTestMethod(Object, Method) afterTestMethod()}
* on the supplied {@link TestContextManager}.
*
* @see #evaluate()
- * @see RunSpringTestContextBefores
+ * @see RunBeforeTestMethodCallbacks
* @author Sam Brannen
* @since 3.0
*/
-public class RunSpringTestContextAfters extends Statement {
+public class RunAfterTestMethodCallbacks extends Statement {
private final Statement next;
@@ -48,7 +48,7 @@ public class RunSpringTestContextAfters extends Statement {
/**
- * Constructs a new RunSpringTestContextAfters statement.
+ * Constructs a new RunAfterTestMethodCallbacks statement.
*
* @param next the next Statement in the execution chain
* @param testInstance the current test instance (never null)
@@ -57,7 +57,7 @@ public class RunSpringTestContextAfters extends Statement {
* @param testContextManager the TestContextManager upon which to call
* afterTestMethod()
*/
- public RunSpringTestContextAfters(Statement next, Object testInstance, Method testMethod,
+ public RunAfterTestMethodCallbacks(Statement next, Object testInstance, Method testMethod,
TestContextManager testContextManager) {
this.next = next;
this.testInstance = testInstance;
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunBeforeTestClassCallbacks.java b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunBeforeTestClassCallbacks.java
new file mode 100644
index 0000000000..6e06239a12
--- /dev/null
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunBeforeTestClassCallbacks.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2002-2009 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.junit4.statements;
+
+import org.junit.runners.model.Statement;
+import org.springframework.test.context.TestContextManager;
+
+/**
+ * RunBeforeTestClassCallbacks is a custom JUnit 4.5+
+ * {@link Statement} which allows the Spring TestContext Framework to
+ * be plugged into the JUnit execution chain by calling
+ * {@link TestContextManager#beforeTestClass() beforeTestClass()} on the
+ * supplied {@link TestContextManager}.
+ *
+ * @see #evaluate()
+ * @see RunAfterTestMethodCallbacks
+ * @author Sam Brannen
+ * @since 3.0
+ */
+public class RunBeforeTestClassCallbacks extends Statement {
+
+ private final Statement next;
+
+ private final TestContextManager testContextManager;
+
+
+ /**
+ * Constructs a new RunBeforeTestClassCallbacks statement.
+ *
+ * @param next the next Statement in the execution chain
+ * @param testContextManager the TestContextManager upon which to call
+ * beforeTestClass()
+ */
+ public RunBeforeTestClassCallbacks(Statement next, TestContextManager testContextManager) {
+ this.next = next;
+ this.testContextManager = testContextManager;
+ }
+
+ /**
+ * Calls {@link TestContextManager#beforeTestClass()} and then invokes the
+ * next {@link Statement} in the execution chain (typically an instance of
+ * {@link org.junit.internal.runners.statements.RunBefores RunBefores}).
+ */
+ @Override
+ public void evaluate() throws Throwable {
+ this.testContextManager.beforeTestClass();
+ this.next.evaluate();
+ }
+
+}
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunSpringTestContextBefores.java b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunBeforeTestMethodCallbacks.java
similarity index 86%
rename from org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunSpringTestContextBefores.java
rename to org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunBeforeTestMethodCallbacks.java
index 1f9e76e866..8833c390b1 100644
--- a/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunSpringTestContextBefores.java
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/junit4/statements/RunBeforeTestMethodCallbacks.java
@@ -22,18 +22,18 @@ import org.junit.runners.model.Statement;
import org.springframework.test.context.TestContextManager;
/**
- * RunSpringTestContextBefores is a custom JUnit 4.5+
+ * RunBeforeTestMethodCallbacks is a custom JUnit 4.5+
* {@link Statement} which allows the Spring TestContext Framework to
* be plugged into the JUnit execution chain by calling
* {@link TestContextManager#beforeTestMethod(Object, Method)
* beforeTestMethod()} on the supplied {@link TestContextManager}.
*
* @see #evaluate()
- * @see RunSpringTestContextAfters
+ * @see RunAfterTestMethodCallbacks
* @author Sam Brannen
* @since 3.0
*/
-public class RunSpringTestContextBefores extends Statement {
+public class RunBeforeTestMethodCallbacks extends Statement {
private final Statement next;
@@ -45,7 +45,7 @@ public class RunSpringTestContextBefores extends Statement {
/**
- * Constructs a new RunSpringTestContextBefores statement.
+ * Constructs a new RunBeforeTestMethodCallbacks statement.
*
* @param next the next Statement in the execution chain
* @param testInstance the current test instance (never null)
@@ -54,7 +54,7 @@ public class RunSpringTestContextBefores extends Statement {
* @param testContextManager the TestContextManager upon which to call
* beforeTestMethod()
*/
- public RunSpringTestContextBefores(Statement next, Object testInstance, Method testMethod,
+ public RunBeforeTestMethodCallbacks(Statement next, Object testInstance, Method testMethod,
TestContextManager testContextManager) {
this.next = next;
this.testInstance = testInstance;
@@ -66,7 +66,7 @@ public class RunSpringTestContextBefores extends Statement {
* Calls {@link TestContextManager#beforeTestMethod(Object, Method)} and
* then invokes the next {@link Statement} in the execution chain (typically
* an instance of {@link org.junit.internal.runners.statements.RunBefores
- * RunBefores} ).
+ * RunBefores}).
*/
@Override
public void evaluate() throws Throwable {
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractTestExecutionListener.java b/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractTestExecutionListener.java
index 4b2ac9223d..e57d1a1daf 100644
--- a/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractTestExecutionListener.java
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractTestExecutionListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2009 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.
@@ -23,13 +23,21 @@ import org.springframework.test.context.TestExecutionListener;
* Abstract implementation of the {@link TestExecutionListener} interface which
* provides empty method stubs. Subclasses can extend this class and override
* only those methods suitable for the task at hand.
- *
+ *
* @author Sam Brannen
* @author Juergen Hoeller
* @since 2.5
*/
public abstract class AbstractTestExecutionListener implements TestExecutionListener {
+ /**
+ * The default implementation is empty. Can be overridden by
+ * subclasses as necessary.
+ */
+ public void beforeTestClass(TestContext testContext) throws Exception {
+ /* no-op */
+ }
+
/**
* The default implementation is empty. Can be overridden by
* subclasses as necessary.
@@ -54,4 +62,12 @@ public abstract class AbstractTestExecutionListener implements TestExecutionList
/* no-op */
}
+ /**
+ * The default implementation is empty. Can be overridden by
+ * subclasses as necessary.
+ */
+ public void afterTestClass(TestContext testContext) throws Exception {
+ /* no-op */
+ }
+
}
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/support/DirtiesContextTestExecutionListener.java b/org.springframework.test/src/main/java/org/springframework/test/context/support/DirtiesContextTestExecutionListener.java
index e3805e335d..98b00eca43 100644
--- a/org.springframework.test/src/main/java/org/springframework/test/context/support/DirtiesContextTestExecutionListener.java
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/support/DirtiesContextTestExecutionListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,16 +20,16 @@ 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.test.annotation.DirtiesContext;
import org.springframework.test.context.TestContext;
import org.springframework.util.Assert;
/**
- * TestExecutionListener which processes test methods configured
- * with the {@link DirtiesContext @DirtiesContext} annotation.
- *
+ * TestExecutionListener which processes test classes and test
+ * methods configured with the {@link DirtiesContext @DirtiesContext}
+ * annotation.
+ *
* @author Sam Brannen
* @author Juergen Hoeller
* @since 2.5
@@ -41,14 +41,27 @@ public class DirtiesContextTestExecutionListener extends AbstractTestExecutionLi
/**
- * If the current test method of the supplied
- * {@link TestContext test context} has been annotated with
- * {@link DirtiesContext @DirtiesContext}, the
- * {@link ApplicationContext application context} of the test context will
- * be {@link TestContext#markApplicationContextDirty() marked as dirty},
- * and the
- * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE}
- * will be set to true in the test context.
+ * Marks the {@link ApplicationContext application context} of the supplied
+ * {@link TestContext test context} as
+ * {@link TestContext#markApplicationContextDirty() dirty}, and sets the
+ * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE
+ * REINJECT_DEPENDENCIES_ATTRIBUTE} in the test context to true
+ * .
+ */
+ protected void dirtyContext(TestContext testContext) {
+ testContext.markApplicationContextDirty();
+ testContext.setAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE, Boolean.TRUE);
+ }
+
+ /**
+ * If the current test method of the supplied {@link TestContext test
+ * context} is annotated with {@link DirtiesContext @DirtiesContext},
+ * the {@link ApplicationContext application context} of the test context
+ * will be {@link TestContext#markApplicationContextDirty() marked as dirty}
+ * , and the
+ * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE
+ * REINJECT_DEPENDENCIES_ATTRIBUTE} in the test context will be set to
+ * true.
*/
@Override
public void afterTestMethod(TestContext testContext) throws Exception {
@@ -59,11 +72,32 @@ public class DirtiesContextTestExecutionListener extends AbstractTestExecutionLi
if (logger.isDebugEnabled()) {
logger.debug("After test method: context [" + testContext + "], dirtiesContext [" + dirtiesContext + "].");
}
-
if (dirtiesContext) {
- testContext.markApplicationContextDirty();
- testContext.setAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE,
- Boolean.TRUE);
+ dirtyContext(testContext);
+ }
+ }
+
+ /**
+ * If the test class of the supplied {@link TestContext test context} is
+ * annotated with {@link DirtiesContext @DirtiesContext}, the
+ * {@link ApplicationContext application context} of the test context will
+ * be {@link TestContext#markApplicationContextDirty() marked as dirty} ,
+ * and the
+ * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE
+ * REINJECT_DEPENDENCIES_ATTRIBUTE} in the test context will be set to
+ * true.
+ */
+ @Override
+ public void afterTestClass(TestContext testContext) throws Exception {
+ Class> testClass = testContext.getTestClass();
+ Assert.notNull(testClass, "The test class of the supplied TestContext must not be null");
+
+ boolean dirtiesContext = testClass.isAnnotationPresent(DirtiesContext.class);
+ if (logger.isDebugEnabled()) {
+ logger.debug("After test class: context [" + testContext + "], dirtiesContext [" + dirtiesContext + "].");
+ }
+ if (dirtiesContext) {
+ dirtyContext(testContext);
}
}
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java b/org.springframework.test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java
index 92bec92761..d2241912df 100644
--- a/org.springframework.test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2009 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.
@@ -16,17 +16,11 @@
package org.springframework.test.context.testng;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.testng.IHookCallBack;
-import org.testng.IHookable;
-import org.testng.ITestResult;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.test.context.ContextConfiguration;
@@ -35,6 +29,13 @@ import org.springframework.test.context.TestContextManager;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
+import org.testng.IHookCallBack;
+import org.testng.IHookable;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
/**
*
- *
- *
+ *
* @author Sam Brannen
* @author Juergen Hoeller
* @since 2.5
@@ -70,7 +71,7 @@ import org.springframework.test.context.support.DirtiesContextTestExecutionListe
* @see org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests
* @see org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
*/
-@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class})
+@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class })
public abstract class AbstractTestNGSpringContextTests implements IHookable, ApplicationContextAware {
/** Logger available to subclasses */
@@ -88,8 +89,8 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
/**
- * Construct a new AbstractTestNGSpringContextTests instance and
- * initializes the internal {@link TestContextManager} for the current test.
+ * Construct a new AbstractTestNGSpringContextTests instance and initialize
+ * the internal {@link TestContextManager} for the current test.
*/
public AbstractTestNGSpringContextTests() {
this.testContextManager = new TestContextManager(getClass());
@@ -98,21 +99,36 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
/**
* Set the {@link ApplicationContext} to be used by this test instance,
* provided via {@link ApplicationContextAware} semantics.
+ *
* @param applicationContext the applicationContext to set
*/
public final void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
+ /**
+ * Delegates to the configured {@link TestContextManager} to call
+ * {@link TestContextManager#beforeTestClass() 'before test class'}
+ * callbacks.
+ *
+ * @throws Exception if a registered TestExecutionListener throws an
+ * exception
+ */
+ @BeforeClass(alwaysRun = true)
+ protected void springTestContextBeforeTestClass() throws Exception {
+ this.testContextManager.beforeTestClass();
+ }
/**
* Delegates to the configured {@link TestContextManager} to
* {@link TestContextManager#prepareTestInstance(Object) prepare} this test
* instance prior to execution of any individual tests, for example for
* injecting dependencies, etc.
- * @throws Exception if a registered TestExecutionListener throws an exception
+ *
+ * @throws Exception if a registered TestExecutionListener throws an
+ * exception
*/
- @BeforeClass(alwaysRun = true)
+ @BeforeClass(alwaysRun = true, dependsOnMethods = "springTestContextBeforeTestClass")
protected void springTestContextPrepareTestInstance() throws Exception {
this.testContextManager.prepareTestInstance(this);
}
@@ -121,6 +137,7 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
* Delegates to the configured {@link TestContextManager} to
* {@link TestContextManager#beforeTestMethod(Object,Method) pre-process}
* the test method before the actual test is executed.
+ *
* @param testMethod the test method which is about to be executed.
* @throws Exception allows all exceptions to propagate.
*/
@@ -130,22 +147,30 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
}
/**
- * Delegates to the
- * {@link IHookCallBack#runTestMethod(ITestResult) test method} in the
- * supplied super();.callback to execute the actual test and then
- * tracks the exception thrown during test execution, if any.
- * @see org.testng.IHookable#run(org.testng.IHookCallBack, org.testng.ITestResult)
+ * Delegates to the {@link IHookCallBack#runTestMethod(ITestResult) test
+ * method} in the supplied callback to execute the actual test
+ * and then tracks the exception thrown during test execution, if any.
+ *
+ * @see org.testng.IHookable#run(org.testng.IHookCallBack,
+ * org.testng.ITestResult)
*/
public void run(IHookCallBack callBack, ITestResult testResult) {
callBack.runTestMethod(testResult);
- this.testException = testResult.getThrowable();
+
+ Throwable testResultException = testResult.getThrowable();
+ if (testResultException instanceof InvocationTargetException) {
+ testResultException = ((InvocationTargetException) testResultException).getCause();
+ }
+ this.testException = testResultException;
}
/**
* Delegates to the configured {@link TestContextManager} to
- * {@link TestContextManager#afterTestMethod(Object, Method, Throwable) post-process}
- * the test method after the actual test has executed.
- * @param testMethod the test method which has just been executed on the test instance
+ * {@link TestContextManager#afterTestMethod(Object, Method, Throwable)
+ * post-process} the test method after the actual test has executed.
+ *
+ * @param testMethod the test method which has just been executed on the
+ * test instance
* @throws Exception allows all exceptions to propagate
*/
@AfterMethod(alwaysRun = true)
@@ -158,4 +183,16 @@ public abstract class AbstractTestNGSpringContextTests implements IHookable, App
}
}
+ /**
+ * Delegates to the configured {@link TestContextManager} to call
+ * {@link TestContextManager#afterTestClass() 'after test class'} callbacks.
+ *
+ * @throws Exception if a registered TestExecutionListener throws an
+ * exception
+ */
+ @AfterClass(alwaysRun = true)
+ protected void springTestContextAfterTestClass() throws Exception {
+ this.testContextManager.afterTestClass();
+ }
+
}
diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/ClassLevelDirtiesContextTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/ClassLevelDirtiesContextTests.java
new file mode 100644
index 0000000000..ecb53d3df3
--- /dev/null
+++ b/org.springframework.test/src/test/java/org/springframework/test/context/ClassLevelDirtiesContextTests.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2002-2009 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.junit4.TrackingRunListener;
+import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
+import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
+
+/**
+ * JUnit 4 based integration test which verifies correct {@link ContextCache
+ * application context caching} in conjunction with the
+ * {@link SpringJUnit4ClassRunner} and the {@link DirtiesContext
+ * @DirtiesContext} annotation at the class level.
+ *
+ * @author Sam Brannen
+ * @since 3.0
+ */
+@RunWith(JUnit4.class)
+public class ClassLevelDirtiesContextTests {
+
+ /**
+ * Asserts the statistics of the supplied context cache.
+ *
+ * @param usageScenario the scenario in which the statistics are used
+ * @param expectedSize the expected number of contexts in the cache
+ * @param expectedHitCount the expected hit count
+ * @param expectedMissCount the expected miss count
+ */
+ private static final void assertContextCacheStatistics(String usageScenario, int expectedSize,
+ int expectedHitCount, int expectedMissCount) {
+
+ ContextCache contextCache = TestContextManager.contextCache;
+ assertEquals("Verifying number of contexts in cache (" + usageScenario + ").", expectedSize,
+ contextCache.size());
+ assertEquals("Verifying number of cache hits (" + usageScenario + ").", expectedHitCount,
+ contextCache.getHitCount());
+ assertEquals("Verifying number of cache misses (" + usageScenario + ").", expectedMissCount,
+ contextCache.getMissCount());
+ }
+
+ private static final void runTestClassAndAssertRunListenerStats(Class> testClass) {
+ final int expectedTestFailureCount = 0;
+ final int expectedTestStartedCount = 1;
+ final int expectedTestFinishedCount = 1;
+
+ TrackingRunListener listener = new TrackingRunListener();
+ JUnitCore jUnitCore = new JUnitCore();
+ jUnitCore.addListener(listener);
+ jUnitCore.run(testClass);
+
+ assertEquals("Verifying number of failures for test class [" + testClass + "].", expectedTestFailureCount,
+ listener.getTestFailureCount());
+ assertEquals("Verifying number of tests started for test class [" + testClass + "].", expectedTestStartedCount,
+ listener.getTestStartedCount());
+ assertEquals("Verifying number of tests finished for test class [" + testClass + "].",
+ expectedTestFinishedCount, listener.getTestFinishedCount());
+ }
+
+ @BeforeClass
+ public static void verifyInitialCacheState() {
+ ContextCache contextCache = TestContextManager.contextCache;
+ contextCache.clear();
+ contextCache.clearStatistics();
+ assertContextCacheStatistics("BeforeClass", 0, 0, 0);
+ }
+
+ @AfterClass
+ public static void verifyFinalCacheState() {
+ assertContextCacheStatistics("AfterClass", 0, 3, 5);
+ }
+
+ @Test
+ public void verifyDirtiesContextBehavior() throws Exception {
+
+ int hits = 0;
+ int misses = 0;
+
+ runTestClassAndAssertRunListenerStats(CleanTestCase.class);
+ assertContextCacheStatistics("after clean test class", 1, hits, ++misses);
+
+ runTestClassAndAssertRunListenerStats(ClassLevelDirtiesContextWithCleanMethodsTestCase.class);
+ assertContextCacheStatistics("after class-level @DirtiesContext with clean test method", 0, ++hits, misses);
+
+ runTestClassAndAssertRunListenerStats(CleanTestCase.class);
+ assertContextCacheStatistics("after clean test class", 1, hits, ++misses);
+
+ runTestClassAndAssertRunListenerStats(ClassLevelDirtiesContextWithDirtyMethodsTestCase.class);
+ assertContextCacheStatistics("after class-level @DirtiesContext with dirty test method", 0, ++hits, misses);
+
+ runTestClassAndAssertRunListenerStats(ClassLevelDirtiesContextWithDirtyMethodsTestCase.class);
+ assertContextCacheStatistics("after class-level @DirtiesContext with dirty test method", 0, hits, ++misses);
+
+ runTestClassAndAssertRunListenerStats(ClassLevelDirtiesContextWithDirtyMethodsTestCase.class);
+ assertContextCacheStatistics("after class-level @DirtiesContext with dirty test method", 0, hits, ++misses);
+
+ runTestClassAndAssertRunListenerStats(CleanTestCase.class);
+ assertContextCacheStatistics("after clean test class", 1, hits, ++misses);
+
+ runTestClassAndAssertRunListenerStats(ClassLevelDirtiesContextWithCleanMethodsTestCase.class);
+ assertContextCacheStatistics("after class-level @DirtiesContext with clean test method", 0, ++hits, misses);
+ }
+
+
+ @RunWith(SpringJUnit4ClassRunner.class)
+ @TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
+ DirtiesContextTestExecutionListener.class })
+ @ContextConfiguration("/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerAppCtxTests-context.xml")
+ public static abstract class BaseTestCase {
+
+ @Autowired
+ protected ApplicationContext applicationContext;
+
+
+ protected void assertApplicationContextWasAutowired() {
+ assertNotNull("The application context should have been autowired.", this.applicationContext);
+ }
+ }
+
+ public static final class CleanTestCase extends BaseTestCase {
+
+ @Test
+ public void verifyContextWasAutowired() {
+ assertApplicationContextWasAutowired();
+ }
+
+ }
+
+ @DirtiesContext
+ public static final class ClassLevelDirtiesContextWithCleanMethodsTestCase extends BaseTestCase {
+
+ @Test
+ public void verifyContextWasAutowired() {
+ assertApplicationContextWasAutowired();
+ }
+ }
+
+ @DirtiesContext
+ public static final class ClassLevelDirtiesContextWithDirtyMethodsTestCase extends BaseTestCase {
+
+ @Test
+ @DirtiesContext
+ public void dirtyContext() {
+ assertApplicationContextWasAutowired();
+ }
+ }
+
+}
diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/SpringRunnerContextCacheTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/SpringRunnerContextCacheTests.java
index e2536d319b..95aa0633b3 100644
--- a/org.springframework.test/src/test/java/org/springframework/test/context/SpringRunnerContextCacheTests.java
+++ b/org.springframework.test/src/test/java/org/springframework/test/context/SpringRunnerContextCacheTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2009 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.
@@ -25,47 +25,49 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
-
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
- * JUnit 4 based unit test which verifies correct
- * {@link ContextCache application context caching} in conjunction with the
- * {@link SpringJUnit4ClassRunner} and the {@link DirtiesContext} annotation.
- *
+ * JUnit 4 based unit test which verifies correct {@link ContextCache
+ * application context caching} in conjunction with the
+ * {@link SpringJUnit4ClassRunner} and the {@link DirtiesContext
+ * @DirtiesContext} annotation at the method level.
+ *
* @author Sam Brannen
* @author Juergen Hoeller
* @since 2.5
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = "/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerAppCtxTests-context.xml")
-public class SpringRunnerContextCacheTests implements ApplicationContextAware {
+@ContextConfiguration("/org/springframework/test/context/junit4/SpringJUnit4ClassRunnerAppCtxTests-context.xml")
+public class SpringRunnerContextCacheTests {
private static ApplicationContext dirtiedApplicationContext;
+ @Autowired
protected ApplicationContext applicationContext;
/**
* Asserts the statistics of the supplied context cache.
+ *
* @param usageScenario the scenario in which the statistics are used
* @param expectedSize the expected number of contexts in the cache
* @param expectedHitCount the expected hit count
* @param expectedMissCount the expected miss count
*/
- public static final void assertContextCacheStatistics(String usageScenario, int expectedSize,
- int expectedHitCount, int expectedMissCount) {
+ public static final void assertContextCacheStatistics(String usageScenario, int expectedSize, int expectedHitCount,
+ int expectedMissCount) {
ContextCache contextCache = TestContextManager.contextCache;
assertEquals("Verifying number of contexts in cache (" + usageScenario + ").", expectedSize,
- contextCache.size());
+ contextCache.size());
assertEquals("Verifying number of cache hits (" + usageScenario + ").", expectedHitCount,
- contextCache.getHitCount());
+ contextCache.getHitCount());
assertEquals("Verifying number of cache misses (" + usageScenario + ").", expectedMissCount,
- contextCache.getMissCount());
+ contextCache.getMissCount());
}
@BeforeClass
@@ -82,37 +84,29 @@ public class SpringRunnerContextCacheTests implements ApplicationContextAware {
assertContextCacheStatistics("AfterClass", 1, 1, 2);
}
-
- public final void setApplicationContext(final ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
- }
-
@Test
@DirtiesContext
public void dirtyContext() {
assertContextCacheStatistics("dirtyContext()", 1, 0, 1);
- assertNotNull("The application context should have been set due to ApplicationContextAware semantics.",
- this.applicationContext);
+ assertNotNull("The application context should have been autowired.", this.applicationContext);
SpringRunnerContextCacheTests.dirtiedApplicationContext = this.applicationContext;
}
@Test
public void verifyContextWasDirtied() {
assertContextCacheStatistics("verifyContextWasDirtied()", 1, 0, 2);
- assertNotNull("The application context should have been set due to ApplicationContextAware semantics.",
- this.applicationContext);
+ assertNotNull("The application context should have been autowired.", this.applicationContext);
assertNotSame("The application context should have been 'dirtied'.",
- SpringRunnerContextCacheTests.dirtiedApplicationContext, this.applicationContext);
+ SpringRunnerContextCacheTests.dirtiedApplicationContext, this.applicationContext);
SpringRunnerContextCacheTests.dirtiedApplicationContext = this.applicationContext;
}
@Test
public void verifyContextWasNotDirtied() {
assertContextCacheStatistics("verifyContextWasNotDirtied()", 1, 1, 2);
- assertNotNull("The application context should have been set due to ApplicationContextAware semantics.",
- this.applicationContext);
+ assertNotNull("The application context should have been autowired.", this.applicationContext);
assertSame("The application context should NOT have been 'dirtied'.",
- SpringRunnerContextCacheTests.dirtiedApplicationContext, this.applicationContext);
+ SpringRunnerContextCacheTests.dirtiedApplicationContext, this.applicationContext);
}
}
diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/ClassLevelDisabledSpringRunnerTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/ClassLevelDisabledSpringRunnerTests.java
index 3f51178362..1c18259f1f 100644
--- a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/ClassLevelDisabledSpringRunnerTests.java
+++ b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/ClassLevelDisabledSpringRunnerTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2009 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.
@@ -17,9 +17,9 @@
package org.springframework.test.context.junit4;
import static org.junit.Assert.fail;
+
import org.junit.Test;
import org.junit.runner.RunWith;
-
import org.springframework.test.annotation.IfProfileValue;
import org.springframework.test.context.TestContext;
import org.springframework.test.context.TestExecutionListener;
@@ -27,6 +27,7 @@ import org.springframework.test.context.TestExecutionListeners;
/**
* @author Juergen Hoeller
+ * @author Sam Brannen
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners(ClassLevelDisabledSpringRunnerTests.CustomTestExecutionListener.class)
@@ -41,6 +42,10 @@ public class ClassLevelDisabledSpringRunnerTests {
public static class CustomTestExecutionListener implements TestExecutionListener {
+ public void beforeTestClass(TestContext testContext) throws Exception {
+ fail("A listener method for a disabled test should never be executed!");
+ }
+
public void prepareTestInstance(TestContext testContext) throws Exception {
fail("A listener method for a disabled test should never be executed!");
}
@@ -52,6 +57,9 @@ public class ClassLevelDisabledSpringRunnerTests {
public void afterTestMethod(TestContext testContext) throws Exception {
fail("A listener method for a disabled test should never be executed!");
}
- }
+ public void afterTestClass(TestContext testContext) throws Exception {
+ fail("A listener method for a disabled test should never be executed!");
+ }
+ }
}
diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4SuiteTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4SuiteTests.java
index d57f39ba27..550ab3cd05 100644
--- a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4SuiteTests.java
+++ b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/SpringJUnit4SuiteTests.java
@@ -19,6 +19,7 @@ package org.springframework.test.context.junit4;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
+import org.springframework.test.context.ClassLevelDirtiesContextTests;
import org.springframework.test.context.SpringRunnerContextCacheTests;
/**
@@ -59,6 +60,7 @@ StandardJUnit4FeaturesTests.class,//
PropertiesBasedSpringJUnit4ClassRunnerAppCtxTests.class,//
CustomDefaultContextLoaderClassSpringRunnerTests.class,//
SpringRunnerContextCacheTests.class,//
+ ClassLevelDirtiesContextTests.class,//
ParameterizedDependencyInjectionTests.class,//
ClassLevelTransactionalSpringRunnerTests.class,//
MethodLevelTransactionalSpringRunnerTests.class,//
diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java
index 30125a76a8..27adaef7ef 100644
--- a/org.springframework.test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java
+++ b/org.springframework.test/src/test/java/org/springframework/test/context/testng/ConcreteTransactionalTestNGSpringContextTests.java
@@ -51,7 +51,6 @@ import org.testng.annotations.Test;
* @author Sam Brannen
* @since 2.5
*/
-@org.junit.Ignore("TestNG tests should not be run by JUnit")
@ContextConfiguration
public class ConcreteTransactionalTestNGSpringContextTests extends AbstractTransactionalTestNGSpringContextTests
implements BeanNameAware, InitializingBean {
diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/testng/DirtiesContextTransactionalTestNGSpringContextTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/testng/DirtiesContextTransactionalTestNGSpringContextTests.java
index be78b46759..f7faa13295 100644
--- a/org.springframework.test/src/test/java/org/springframework/test/context/testng/DirtiesContextTransactionalTestNGSpringContextTests.java
+++ b/org.springframework.test/src/test/java/org/springframework/test/context/testng/DirtiesContextTransactionalTestNGSpringContextTests.java
@@ -32,7 +32,7 @@ import org.testng.annotations.Test;
* TestNG based unit test to assess the claim in SPR-3880 that a "context marked dirty using
- * {@link DirtiesContext @DirtiesContext} in [a] TestNG based test is not
+ * {@link DirtiesContext @DirtiesContext} in [a] TestNG based test is not
* reloaded in subsequent tests".
*
@@ -47,7 +47,6 @@ import org.testng.annotations.Test; * @author Sam Brannen * @since 2.5 */ -@org.junit.Ignore("TestNG tests should not be run by JUnit") @ContextConfiguration public class DirtiesContextTransactionalTestNGSpringContextTests extends AbstractTransactionalTestNGSpringContextTests { @@ -82,4 +81,5 @@ public class DirtiesContextTransactionalTestNGSpringContextTests extends Abstrac assertSame(this.applicationContext, this.dirtiedApplicationContext, "The application context should NOT have been 'dirtied'."); } + }