diff --git a/spring-test/src/main/java/org/springframework/test/annotation/DirtiesContext.java b/spring-test/src/main/java/org/springframework/test/annotation/DirtiesContext.java index 004217f16ec..73bf379df39 100644 --- a/spring-test/src/main/java/org/springframework/test/annotation/DirtiesContext.java +++ b/spring-test/src/main/java/org/springframework/test/annotation/DirtiesContext.java @@ -64,10 +64,16 @@ import java.lang.annotation.Target; * {@link ClassMode#AFTER_CLASS AFTER_CLASS} * * + *

{@code BEFORE_*} modes are supported by the + * {@link org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener DirtiesContextBeforeModesTestExecutionListener}; + * {@code AFTER_*} modes are supported by the + * {@link org.springframework.test.context.support.DirtiesContextTestExecutionListener DirtiesContextTestExecutionListener}. + * * @author Sam Brannen * @author Rod Johnson * @since 2.0 * @see org.springframework.test.context.ContextConfiguration + * @see org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener * @see org.springframework.test.context.support.DirtiesContextTestExecutionListener */ @Documented diff --git a/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java b/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java index 72b300be0c7..d16b05f8cf4 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java @@ -28,6 +28,7 @@ import org.springframework.test.context.TestContext; 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.DirtiesContextBeforeModesTestExecutionListener; import org.springframework.test.context.support.DirtiesContextTestExecutionListener; import org.springframework.test.context.web.ServletTestExecutionListener; @@ -51,6 +52,7 @@ import org.springframework.test.context.web.ServletTestExecutionListener; * *

@@ -77,14 +79,15 @@ import org.springframework.test.context.web.ServletTestExecutionListener; * @see TestContextManager * @see TestExecutionListeners * @see ServletTestExecutionListener + * @see DirtiesContextBeforeModesTestExecutionListener * @see DependencyInjectionTestExecutionListener * @see DirtiesContextTestExecutionListener * @see AbstractTransactionalJUnit4SpringContextTests * @see org.springframework.test.context.testng.AbstractTestNGSpringContextTests */ @RunWith(SpringJUnit4ClassRunner.class) -@TestExecutionListeners({ServletTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, - DirtiesContextTestExecutionListener.class}) +@TestExecutionListeners({ ServletTestExecutionListener.class, DirtiesContextBeforeModesTestExecutionListener.class, + DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class }) public abstract class AbstractJUnit4SpringContextTests implements ApplicationContextAware { /** diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractDirtiesContextTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractDirtiesContextTestExecutionListener.java new file mode 100644 index 00000000000..dbf1fa6f71a --- /dev/null +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractDirtiesContextTestExecutionListener.java @@ -0,0 +1,151 @@ +/* + * Copyright 2002-2015 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.support; + +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.annotation.AnnotatedElementUtils; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.annotation.DirtiesContext.HierarchyMode; +import org.springframework.test.annotation.DirtiesContext.MethodMode; +import org.springframework.test.context.TestContext; +import org.springframework.util.Assert; + +/** + * Abstract base class for {@code TestExecutionListener} implementations that + * provide support for marking the {@code ApplicationContext} associated with + * a test as dirty for both test classes and test methods annotated + * with the {@link DirtiesContext @DirtiesContext} annotation. + * + *

The core functionality for this class was extracted from + * {@link DirtiesContextTestExecutionListener} in Spring Framework 4.2. + * + * @author Sam Brannen + * @author Juergen Hoeller + * @since 4.2 + * @see DirtiesContext + */ +public abstract class AbstractDirtiesContextTestExecutionListener extends AbstractTestExecutionListener { + + private static final Log logger = LogFactory.getLog(AbstractDirtiesContextTestExecutionListener.class); + + + @Override + public abstract int getOrder(); + + /** + * Mark the {@linkplain ApplicationContext application context} of the supplied + * {@linkplain TestContext test context} as + * {@linkplain TestContext#markApplicationContextDirty(DirtiesContext.HierarchyMode) dirty} + * and set {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE + * REINJECT_DEPENDENCIES_ATTRIBUTE} in the test context to {@code true}. + * @param testContext the test context whose application context should + * be marked as dirty + * @param hierarchyMode the context cache clearing mode to be applied if the + * context is part of a hierarchy; may be {@code null} + * @since 3.2.2 + */ + protected void dirtyContext(TestContext testContext, HierarchyMode hierarchyMode) { + testContext.markApplicationContextDirty(hierarchyMode); + testContext.setAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE, Boolean.TRUE); + } + + /** + * Perform the actual work for {@link #beforeTestMethod} and {@link #afterTestMethod} + * by dirtying the context if appropriate (i.e., according to the required modes). + * @param testContext the test context whose application context should + * potentially be marked as dirty; never {@code null} + * @param requiredMethodMode the method mode required for a context to + * be marked dirty in the current phase; never {@code null} + * @param requiredClassMode the class mode required for a context to + * be marked dirty in the current phase; never {@code null} + * @throws Exception allows any exception to propagate + * @since 4.2 + * @see #dirtyContext + */ + protected void beforeOrAfterTestMethod(TestContext testContext, MethodMode requiredMethodMode, + ClassMode requiredClassMode) throws Exception { + + Assert.notNull(testContext, "TestContext must not be null"); + Assert.notNull(requiredMethodMode, "requiredMethodMode must not be null"); + Assert.notNull(requiredClassMode, "requiredClassMode must not be null"); + + Class testClass = testContext.getTestClass(); + Method testMethod = testContext.getTestMethod(); + Assert.notNull(testClass, "The test class of the supplied TestContext must not be null"); + Assert.notNull(testMethod, "The test method of the supplied TestContext must not be null"); + + DirtiesContext methodAnn = AnnotatedElementUtils.findMergedAnnotation(testMethod, DirtiesContext.class); + DirtiesContext classAnn = AnnotatedElementUtils.findMergedAnnotation(testClass, DirtiesContext.class); + boolean methodAnnotated = (methodAnn != null); + boolean classAnnotated = (classAnn != null); + MethodMode methodMode = (methodAnnotated ? methodAnn.methodMode() : null); + ClassMode classMode = (classAnnotated ? classAnn.classMode() : null); + + if (logger.isDebugEnabled()) { + String phase = (requiredClassMode.name().startsWith("BEFORE") ? "Before" : "After"); + logger.debug(String.format("%s test method: context %s, class annotated with @DirtiesContext [%s] " + + "with mode [%s], method annotated with @DirtiesContext [%s] with mode [%s].", phase, testContext, + classAnnotated, classMode, methodAnnotated, methodMode)); + } + + if ((methodMode == requiredMethodMode) || (classMode == requiredClassMode)) { + HierarchyMode hierarchyMode = (methodAnnotated ? methodAnn.hierarchyMode() : classAnn.hierarchyMode()); + dirtyContext(testContext, hierarchyMode); + } + } + + /** + * Perform the actual work for {@link #beforeTestClass} and {@link #afterTestClass} + * by dirtying the context if appropriate (i.e., according to the required mode). + * @param testContext the test context whose application context should + * potentially be marked as dirty; never {@code null} + * @param requiredClassMode the class mode required for a context to + * be marked dirty in the current phase; never {@code null} + * @throws Exception allows any exception to propagate + * @since 4.2 + * @see #dirtyContext + */ + protected void beforeOrAfterTestClass(TestContext testContext, ClassMode requiredClassMode) throws Exception { + Assert.notNull(testContext, "TestContext must not be null"); + Assert.notNull(requiredClassMode, "requiredClassMode must not be null"); + + Class testClass = testContext.getTestClass(); + Assert.notNull(testClass, "The test class of the supplied TestContext must not be null"); + + DirtiesContext dirtiesContext = AnnotatedElementUtils.findMergedAnnotation(testClass, DirtiesContext.class); + boolean classAnnotated = (dirtiesContext != null); + ClassMode classMode = (classAnnotated ? dirtiesContext.classMode() : null); + + if (logger.isDebugEnabled()) { + String phase = (requiredClassMode.name().startsWith("BEFORE") ? "Before" : "After"); + logger.debug(String.format( + "%s test class: context %s, class annotated with @DirtiesContext [%s] with mode [%s].", phase, + testContext, classAnnotated, classMode)); + } + + if (classMode == requiredClassMode) { + dirtyContext(testContext, dirtiesContext.hierarchyMode()); + } + } + +} diff --git a/spring-test/src/main/java/org/springframework/test/context/support/DirtiesContextBeforeModesTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/support/DirtiesContextBeforeModesTestExecutionListener.java new file mode 100644 index 00000000000..49504c406ba --- /dev/null +++ b/spring-test/src/main/java/org/springframework/test/context/support/DirtiesContextBeforeModesTestExecutionListener.java @@ -0,0 +1,98 @@ +/* + * Copyright 2002-2015 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.support; + +import org.springframework.context.ApplicationContext; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.DirtiesContext.ClassMode; +import org.springframework.test.annotation.DirtiesContext.MethodMode; +import org.springframework.test.context.TestContext; +import org.springframework.test.context.TestExecutionListeners; + +import static org.springframework.test.annotation.DirtiesContext.ClassMode.*; +import static org.springframework.test.annotation.DirtiesContext.MethodMode.*; + +/** + * {@code TestExecutionListener} which provides support for marking the + * {@code ApplicationContext} associated with a test as dirty for + * both test classes and test methods annotated with the + * {@link DirtiesContext @DirtiesContext} annotation. + * + *

This listener supports test methods with the + * {@linkplain DirtiesContext#methodMode method mode} set to + * {@link MethodMode#BEFORE_METHOD BEFORE_METHOD} and test classes with the + * {@linkplain DirtiesContext#classMode() class mode} set to + * {@link ClassMode#BEFORE_EACH_TEST_METHOD BEFORE_EACH_TEST_METHOD} or + * {@link ClassMode#BEFORE_CLASS BEFORE_CLASS}. For support for AFTER + * modes, see {@link DirtiesContextTestExecutionListener}. + * + *

When {@linkplain TestExecutionListeners#mergeMode merging} + * {@code TestExecutionListeners} with the defaults, this listener will + * automatically be ordered before the {@link DependencyInjectionTestExecutionListener}; + * otherwise, this listener must be manually configured to execute before the + * {@code DependencyInjectionTestExecutionListener}. + * + * @author Sam Brannen + * @since 4.2 + * @see DirtiesContext + * @see DirtiesContextTestExecutionListener + */ +public class DirtiesContextBeforeModesTestExecutionListener extends AbstractDirtiesContextTestExecutionListener { + + /** + * Returns {@code 1500}. + */ + @Override + public final int getOrder() { + return 1500; + } + + /** + * If the test class of the supplied {@linkplain TestContext test context} + * is annotated with {@code @DirtiesContext} and the {@linkplain + * DirtiesContext#classMode() class mode} is set to {@link + * ClassMode#BEFORE_CLASS BEFORE_CLASS}, the {@linkplain ApplicationContext + * application context} of the test context will be + * {@linkplain TestContext#markApplicationContextDirty marked as dirty}, and the + * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE + * REINJECT_DEPENDENCIES_ATTRIBUTE} in the test context will be set to + * {@code true}. + */ + @Override + public void beforeTestClass(TestContext testContext) throws Exception { + beforeOrAfterTestClass(testContext, BEFORE_CLASS); + } + + /** + * If the current test method of the supplied {@linkplain TestContext test + * context} is annotated with {@code @DirtiesContext} and the {@linkplain + * DirtiesContext#methodMode() method mode} is set to {@link + * MethodMode#BEFORE_METHOD BEFORE_METHOD}, or if the test class is + * annotated with {@code @DirtiesContext} and the {@linkplain + * DirtiesContext#classMode() class mode} is set to {@link + * ClassMode#BEFORE_EACH_TEST_METHOD BEFORE_EACH_TEST_METHOD}, the + * {@linkplain ApplicationContext application context} of the test context + * will be {@linkplain TestContext#markApplicationContextDirty marked as dirty} and the + * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE + * REINJECT_DEPENDENCIES_ATTRIBUTE} in the test context will be set to {@code true}. + */ + @Override + public void beforeTestMethod(TestContext testContext) throws Exception { + beforeOrAfterTestMethod(testContext, BEFORE_METHOD, BEFORE_EACH_TEST_METHOD); + } + +} diff --git a/spring-test/src/main/java/org/springframework/test/context/support/DirtiesContextTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/support/DirtiesContextTestExecutionListener.java index 67f851f6205..5c0f552a429 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/DirtiesContextTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/DirtiesContextTestExecutionListener.java @@ -16,19 +16,12 @@ package org.springframework.test.context.support; -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.annotation.AnnotatedElementUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; -import org.springframework.test.annotation.DirtiesContext.HierarchyMode; import org.springframework.test.annotation.DirtiesContext.MethodMode; import org.springframework.test.context.TestContext; -import org.springframework.util.Assert; +import org.springframework.test.context.TestExecutionListeners; import static org.springframework.test.annotation.DirtiesContext.ClassMode.*; import static org.springframework.test.annotation.DirtiesContext.MethodMode.*; @@ -39,15 +32,26 @@ import static org.springframework.test.annotation.DirtiesContext.MethodMode.*; * both test classes and test methods annotated with the * {@link DirtiesContext @DirtiesContext} annotation. * + *

This listener supports test methods with the + * {@linkplain DirtiesContext#methodMode method mode} set to + * {@link MethodMode#AFTER_METHOD AFTER_METHOD} and test classes with the + * {@linkplain DirtiesContext#classMode() class mode} set to + * {@link ClassMode#AFTER_EACH_TEST_METHOD AFTER_EACH_TEST_METHOD} or + * {@link ClassMode#AFTER_CLASS AFTER_CLASS}. For support for BEFORE + * modes, see {@link DirtiesContextBeforeModesTestExecutionListener}. + * + *

When {@linkplain TestExecutionListeners#mergeMode merging} + * {@code TestExecutionListeners} with the defaults, this listener will + * automatically be ordered after the {@link DependencyInjectionTestExecutionListener}; + * otherwise, this listener must be manually configured to execute after the + * {@code DependencyInjectionTestExecutionListener}. + * * @author Sam Brannen - * @author Juergen Hoeller * @since 2.5 * @see DirtiesContext + * @see DirtiesContextBeforeModesTestExecutionListener */ -public class DirtiesContextTestExecutionListener extends AbstractTestExecutionListener { - - private static final Log logger = LogFactory.getLog(DirtiesContextTestExecutionListener.class); - +public class DirtiesContextTestExecutionListener extends AbstractDirtiesContextTestExecutionListener { /** * Returns {@code 3000}. @@ -57,41 +61,6 @@ public class DirtiesContextTestExecutionListener extends AbstractTestExecutionLi return 3000; } - /** - * If the test class of the supplied {@linkplain TestContext test context} - * is annotated with {@code @DirtiesContext} and the {@linkplain - * DirtiesContext#classMode() class mode} is set to {@link - * ClassMode#BEFORE_CLASS BEFORE_CLASS}, the {@linkplain ApplicationContext - * application context} of the test context will be - * {@linkplain TestContext#markApplicationContextDirty marked as dirty}, and the - * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE - * REINJECT_DEPENDENCIES_ATTRIBUTE} in the test context will be set to - * {@code true}. - */ - @Override - public void beforeTestClass(TestContext testContext) throws Exception { - beforeOrAfterTestClass(testContext, "Before", BEFORE_CLASS); - } - - /** - * If the current test method of the supplied {@linkplain TestContext test - * context} is annotated with {@code @DirtiesContext} and the {@linkplain - * DirtiesContext#methodMode() method mode} is set to {@link - * MethodMode#BEFORE_METHOD BEFORE_METHOD}, or if the test class is - * annotated with {@code @DirtiesContext} and the {@linkplain - * DirtiesContext#classMode() class mode} is set to {@link - * ClassMode#BEFORE_EACH_TEST_METHOD BEFORE_EACH_TEST_METHOD}, the - * {@linkplain ApplicationContext application context} of the test context - * will be {@linkplain TestContext#markApplicationContextDirty marked as dirty} and the - * {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE - * REINJECT_DEPENDENCIES_ATTRIBUTE} in the test context will be set to {@code true}. - * @since 4.2 - */ - @Override - public void beforeTestMethod(TestContext testContext) throws Exception { - beforeOrAfterTestMethod(testContext, "Before", BEFORE_METHOD, BEFORE_EACH_TEST_METHOD); - } - /** * If the current test method of the supplied {@linkplain TestContext test * context} is annotated with {@code @DirtiesContext} and the {@linkplain @@ -107,7 +76,7 @@ public class DirtiesContextTestExecutionListener extends AbstractTestExecutionLi */ @Override public void afterTestMethod(TestContext testContext) throws Exception { - beforeOrAfterTestMethod(testContext, "After", AFTER_METHOD, AFTER_EACH_TEST_METHOD); + beforeOrAfterTestMethod(testContext, AFTER_METHOD, AFTER_EACH_TEST_METHOD); } /** @@ -123,79 +92,7 @@ public class DirtiesContextTestExecutionListener extends AbstractTestExecutionLi */ @Override public void afterTestClass(TestContext testContext) throws Exception { - beforeOrAfterTestClass(testContext, "After", AFTER_CLASS); - } - - /** - * Marks the {@linkplain ApplicationContext application context} of the supplied - * {@linkplain TestContext test context} as - * {@linkplain TestContext#markApplicationContextDirty(DirtiesContext.HierarchyMode) dirty} - * and sets {@link DependencyInjectionTestExecutionListener#REINJECT_DEPENDENCIES_ATTRIBUTE - * REINJECT_DEPENDENCIES_ATTRIBUTE} in the test context to {@code true}. - * @param testContext the test context whose application context should - * marked as dirty - * @param hierarchyMode the context cache clearing mode to be applied if the - * context is part of a hierarchy; may be {@code null} - * @since 3.2.2 - */ - protected void dirtyContext(TestContext testContext, HierarchyMode hierarchyMode) { - testContext.markApplicationContextDirty(hierarchyMode); - testContext.setAttribute(DependencyInjectionTestExecutionListener.REINJECT_DEPENDENCIES_ATTRIBUTE, Boolean.TRUE); - } - - /** - * Perform the actual work for {@link #beforeTestMethod} and {@link #afterTestMethod}. - * @since 4.2 - */ - private void beforeOrAfterTestMethod(TestContext testContext, String phase, MethodMode requiredMethodMode, - ClassMode requiredClassMode) throws Exception { - - Class testClass = testContext.getTestClass(); - Method testMethod = testContext.getTestMethod(); - Assert.notNull(testClass, "The test class of the supplied TestContext must not be null"); - Assert.notNull(testMethod, "The test method of the supplied TestContext must not be null"); - - DirtiesContext methodAnn = AnnotatedElementUtils.findMergedAnnotation(testMethod, DirtiesContext.class); - DirtiesContext classAnn = AnnotatedElementUtils.findMergedAnnotation(testClass, DirtiesContext.class); - boolean methodAnnotated = (methodAnn != null); - boolean classAnnotated = (classAnn != null); - MethodMode methodMode = (methodAnnotated ? methodAnn.methodMode() : null); - ClassMode classMode = (classAnnotated ? classAnn.classMode() : null); - - if (logger.isDebugEnabled()) { - logger.debug(String.format("%s test method: context %s, class annotated with @DirtiesContext [%s] " - + "with mode [%s], method annotated with @DirtiesContext [%s] with mode [%s].", phase, testContext, - classAnnotated, classMode, methodAnnotated, methodMode)); - } - - if ((methodMode == requiredMethodMode) || (classMode == requiredClassMode)) { - HierarchyMode hierarchyMode = (methodAnnotated ? methodAnn.hierarchyMode() : classAnn.hierarchyMode()); - dirtyContext(testContext, hierarchyMode); - } - } - - /** - * Perform the actual work for {@link #beforeTestClass} and {@link #afterTestClass}. - * @since 4.2 - */ - private void beforeOrAfterTestClass(TestContext testContext, String phase, ClassMode requiredClassMode) - throws Exception { - Class testClass = testContext.getTestClass(); - Assert.notNull(testClass, "The test class of the supplied TestContext must not be null"); - - DirtiesContext dirtiesContext = AnnotatedElementUtils.findMergedAnnotation(testClass, DirtiesContext.class); - boolean classAnnotated = (dirtiesContext != null); - ClassMode classMode = (classAnnotated ? dirtiesContext.classMode() : null); - - if (logger.isDebugEnabled()) { - logger.debug(String.format( - "%s test class: context %s, class annotated with @DirtiesContext [%s] with mode [%s].", phase, - testContext, classAnnotated, classMode)); - } - - if (classMode == requiredClassMode) { - dirtyContext(testContext, dirtiesContext.hierarchyMode()); - } + beforeOrAfterTestClass(testContext, AFTER_CLASS); } } diff --git a/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java b/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java index 9becd20bd04..2be1967b386 100644 --- a/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java +++ b/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTestNGSpringContextTests.java @@ -21,13 +21,6 @@ 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.AfterClass; -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; @@ -36,9 +29,18 @@ import org.springframework.test.context.TestContext; 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.DirtiesContextBeforeModesTestExecutionListener; import org.springframework.test.context.support.DirtiesContextTestExecutionListener; import org.springframework.test.context.web.ServletTestExecutionListener; +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; + /** * Abstract base test class which integrates the Spring TestContext Framework * with explicit {@link ApplicationContext} testing support in a TestNG @@ -64,6 +66,7 @@ import org.springframework.test.context.web.ServletTestExecutionListener; * *

@@ -76,13 +79,14 @@ import org.springframework.test.context.web.ServletTestExecutionListener; * @see TestContextManager * @see TestExecutionListeners * @see ServletTestExecutionListener + * @see DirtiesContextBeforeModesTestExecutionListener * @see DependencyInjectionTestExecutionListener * @see DirtiesContextTestExecutionListener * @see AbstractTransactionalTestNGSpringContextTests * @see org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests */ -@TestExecutionListeners({ServletTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, - DirtiesContextTestExecutionListener.class}) +@TestExecutionListeners({ ServletTestExecutionListener.class, DirtiesContextBeforeModesTestExecutionListener.class, + DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class }) public abstract class AbstractTestNGSpringContextTests implements IHookable, ApplicationContextAware { /** Logger available to subclasses */ diff --git a/spring-test/src/main/resources/META-INF/spring.factories b/spring-test/src/main/resources/META-INF/spring.factories index 6bd598dc639..012b38df910 100644 --- a/spring-test/src/main/resources/META-INF/spring.factories +++ b/spring-test/src/main/resources/META-INF/spring.factories @@ -1,7 +1,8 @@ # Default TestExecutionListeners for the Spring TestContext Framework # org.springframework.test.context.TestExecutionListener = \ - org.springframework.test.context.web.ServletTestExecutionListener,\ + org.springframework.test.context.web.ServletTestExecutionListener,\ + org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener,\ org.springframework.test.context.support.DependencyInjectionTestExecutionListener,\ org.springframework.test.context.support.DirtiesContextTestExecutionListener,\ org.springframework.test.context.transaction.TransactionalTestExecutionListener,\ diff --git a/spring-test/src/test/java/org/springframework/test/context/TestExecutionListenersTests.java b/spring-test/src/test/java/org/springframework/test/context/TestExecutionListenersTests.java index 650bd09834a..886f2526403 100644 --- a/spring-test/src/test/java/org/springframework/test/context/TestExecutionListenersTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/TestExecutionListenersTests.java @@ -19,7 +19,6 @@ package org.springframework.test.context; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; -import java.util.stream.Collectors; import org.junit.Test; @@ -28,11 +27,13 @@ import org.springframework.core.annotation.AnnotationConfigurationException; import org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener; import org.springframework.test.context.support.AbstractTestExecutionListener; import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; +import org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener; import org.springframework.test.context.support.DirtiesContextTestExecutionListener; import org.springframework.test.context.transaction.TransactionalTestExecutionListener; import org.springframework.test.context.web.ServletTestExecutionListener; import static java.util.Arrays.*; +import static java.util.stream.Collectors.*; import static org.junit.Assert.*; import static org.springframework.test.context.TestExecutionListeners.MergeMode.*; @@ -40,7 +41,7 @@ import static org.springframework.test.context.TestExecutionListeners.MergeMode. * Unit tests for the {@link TestExecutionListeners @TestExecutionListeners} * annotation, which verify: *