diff --git a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java index d21a8168957..c3fbbeff812 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestExecutionListener.java @@ -42,6 +42,35 @@ package org.springframework.test.context; * {@link org.springframework.core.annotation.Order @Order} annotation. See * {@link TestContextBootstrapper#getTestExecutionListeners()} for details. * + *

Wrapping Behavior for Listeners

+ * + *

The {@link TestContextManager} guarantees wrapping behavior for + * multiple registered listeners that implement lifecycle callbacks such as + * {@link #beforeTestClass(TestContext) beforeTestClass}, + * {@link #afterTestClass(TestContext) afterTestClass}, + * {@link #beforeTestMethod(TestContext) beforeTestMethod}, + * {@link #afterTestMethod(TestContext) afterTestMethod}, + * {@link #beforeTestExecution(TestContext) beforeTestExecution}, and + * {@link #afterTestExecution(TestContext) afterTestExecution}. This means that, + * given two listeners {@code Listener1} and {@code Listener2} with {@code Listener1} + * registered before {@code Listener2}, any before callbacks implemented + * by {@code Listener1} are guaranteed to be invoked before any + * before callbacks implemented by {@code Listener2}. Similarly, given + * the same two listeners registered in the same order, any after + * callbacks implemented by {@code Listener1} are guaranteed to be invoked + * after any after callbacks implemented by + * {@code Listener2}. {@code Listener1} is therefore said to wrap + * {@code Listener2}. + * + *

For a concrete example, consider the relationship between the + * {@link org.springframework.test.context.transaction.TransactionalTestExecutionListener + * TransactionalTestExecutionListener} and the + * {@link org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener + * SqlScriptsTestExecutionListener}. The {@code SqlScriptsTestExecutionListener} + * is registered after the {@code TransactionalTestExecutionListener}, so that + * SQL scripts are executed within a transaction managed by the + * {@code TransactionalTestExecutionListener}. + * *

Registering TestExecutionListener Implementations

* *

A {@code TestExecutionListener} can be registered explicitly for a test class, @@ -101,6 +130,8 @@ public interface TestExecutionListener { * the class. *

This method should be called immediately before framework-specific * before class lifecycle callbacks. + *

See the {@linkplain TestExecutionListener class-level documentation} + * for details on wrapping behavior for lifecycle callbacks. *

The default implementation is empty. Can be overridden by * concrete classes as necessary. * @param testContext the test context for the test; never {@code null} @@ -119,6 +150,8 @@ public interface TestExecutionListener { * {@link org.springframework.test.context.junit4.rules.SpringMethodRule * SpringMethodRule}). In any case, this method must be called prior to any * framework-specific lifecycle callbacks. + *

See the {@linkplain TestExecutionListener class-level documentation} + * for details on wrapping behavior for listeners. *

The default implementation is empty. Can be overridden by * concrete classes as necessary. * @param testContext the test context for the test; never {@code null} @@ -138,6 +171,8 @@ public interface TestExecutionListener { * this method might be something like {@code beforeTestSetUp} or * {@code beforeEach}; however, it is unfortunately impossible to rename * this method due to backward compatibility concerns. + *

See the {@linkplain TestExecutionListener class-level documentation} + * for details on wrapping behavior for lifecycle callbacks. *

The default implementation is empty. Can be overridden by * concrete classes as necessary. * @param testContext the test context in which the test method will be @@ -157,6 +192,8 @@ public interface TestExecutionListener { * or logging purposes. *

This method must be called after framework-specific * before lifecycle callbacks. + *

See the {@linkplain TestExecutionListener class-level documentation} + * for details on wrapping behavior for lifecycle callbacks. *

The default implementation is empty. Can be overridden by * concrete classes as necessary. * @param testContext the test context in which the test method will be @@ -177,6 +214,8 @@ public interface TestExecutionListener { * or logging purposes. *

This method must be called before framework-specific * after lifecycle callbacks. + *

See the {@linkplain TestExecutionListener class-level documentation} + * for details on wrapping behavior for lifecycle callbacks. *

The default implementation is empty. Can be overridden by * concrete classes as necessary. * @param testContext the test context in which the test method will be @@ -201,6 +240,8 @@ public interface TestExecutionListener { * this method might be something like {@code afterTestTearDown} or * {@code afterEach}; however, it is unfortunately impossible to rename * this method due to backward compatibility concerns. + *

See the {@linkplain TestExecutionListener class-level documentation} + * for details on wrapping behavior for lifecycle callbacks. *

The default implementation is empty. Can be overridden by * concrete classes as necessary. * @param testContext the test context in which the test method was @@ -218,6 +259,8 @@ public interface TestExecutionListener { * the class. *

This method should be called immediately after framework-specific * after class lifecycle callbacks. + *

See the {@linkplain TestExecutionListener class-level documentation} + * for details on wrapping behavior for lifecycle callbacks. *

The default implementation is empty. Can be overridden by * concrete classes as necessary. * @param testContext the test context for the test; never {@code null}