diff --git a/spring-test/src/main/java/org/springframework/test/context/transaction/AfterTransaction.java b/spring-test/src/main/java/org/springframework/test/context/transaction/AfterTransaction.java index aeaac1355b..a7f6653e88 100644 --- a/spring-test/src/main/java/org/springframework/test/context/transaction/AfterTransaction.java +++ b/spring-test/src/main/java/org/springframework/test/context/transaction/AfterTransaction.java @@ -23,12 +23,16 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - *
Test annotation to indicate that the annotated {@code void} method + *
Test annotation which indicates that the annotated {@code void} method * should be executed after a transaction is ended for a test method - * configured to run within a transaction via the {@code @Transactional} annotation. + * configured to run within a transaction via Spring's {@code @Transactional} + * annotation. * - *
The {@code @AfterTransaction} methods of superclasses will be executed - * after those of the current class. + *
As of Spring Framework 4.3, {@code @AfterTransaction} may be declared on + * Java 8 based interface default methods. + * + *
{@code @AfterTransaction} methods declared in superclasses or as interface + * default methods will be executed after those of the current test class. * *
As of Spring Framework 4.0, this annotation may be used as a * meta-annotation to create custom composed annotations. diff --git a/spring-test/src/main/java/org/springframework/test/context/transaction/BeforeTransaction.java b/spring-test/src/main/java/org/springframework/test/context/transaction/BeforeTransaction.java index 418a077bf4..217c7d1768 100644 --- a/spring-test/src/main/java/org/springframework/test/context/transaction/BeforeTransaction.java +++ b/spring-test/src/main/java/org/springframework/test/context/transaction/BeforeTransaction.java @@ -23,12 +23,16 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - *
Test annotation to indicate that the annotated {@code void} method + *
Test annotation which indicates that the annotated {@code void} method * should be executed before a transaction is started for a test method - * configured to run within a transaction via the {@code @Transactional} annotation. + * configured to run within a transaction via Spring's {@code @Transactional} + * annotation. * - *
The {@code @BeforeTransaction} methods of superclasses will be executed - * before those of the current class. + *
As of Spring Framework 4.3, {@code @BeforeTransaction} may be declared on + * Java 8 based interface default methods. + * + *
{@code @BeforeTransaction} methods declared in superclasses or as interface + * default methods will be executed before those of the current test class. * *
As of Spring Framework 4.0, this annotation may be used as a * meta-annotation to create custom composed annotations. diff --git a/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java index d81f1ddaa4..adb3cfa144 100644 --- a/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java @@ -97,9 +97,10 @@ import org.springframework.util.StringUtils; *
When executing transactional tests, it is sometimes useful to be able to * execute certain set up or tear down code outside of a * transaction. {@code TransactionalTestExecutionListener} provides such - * support for methods annotated with - * {@link BeforeTransaction @BeforeTransaction} or - * {@link AfterTransaction @AfterTransaction}. + * support for methods annotated with {@link BeforeTransaction @BeforeTransaction} + * or {@link AfterTransaction @AfterTransaction}. As of Spring Framework 4.3, + * {@code @BeforeTransaction} and {@code @AfterTransaction} may also be declared + * on Java 8 based interface default methods. * *
{@code TransactionalTestExecutionListener} expects a @@ -431,90 +432,23 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis } /** - * Gets all superclasses of the supplied {@link Class class}, including the - * class itself. The ordering of the returned list will begin with the - * supplied class and continue up the class hierarchy, excluding {@link Object}. - *
Note: This code has been borrowed from
- * {@link org.junit.internal.runners.TestClass#getSuperClasses(Class)} and
- * adapted.
- * @param clazz the class for which to retrieve the superclasses
- * @return all superclasses of the supplied class, excluding {@code Object}
- */
- private List Note: This code has been borrowed from
- * {@link org.junit.internal.runners.TestClass#getAnnotatedMethods(Class)}
- * and adapted.
+ * Default methods on interfaces are also detected.
* @param clazz the class for which to retrieve the annotated methods
* @param annotationType the annotation type for which to search
* @return all annotated methods in the supplied class and its superclasses
+ * as well as annotated interface default methods
*/
private List Note: This code has been borrowed from
- * {@link org.junit.internal.runners.TestClass#isShadowed(Method, List)}.
- * @param method the method to check for shadowing
- * @param previousMethods the list of methods which have previously been processed
- * @return {@code true} if the supplied method is shadowed by a
- * method in the {@code previousMethods} list
- */
- private boolean isShadowed(Method method, List Note: This code has been borrowed from
- * {@link org.junit.internal.runners.TestClass#isShadowed(Method, Method)}.
- * @param current the current method
- * @param previous the previous method
- * @return {@code true} if the previous method shadows the current one
- */
- private boolean isShadowed(Method current, Method previous) {
- if (!previous.getName().equals(current.getName())) {
- return false;
- }
- if (previous.getParameterTypes().length != current.getParameterTypes().length) {
- return false;
- }
- for (int i = 0; i < previous.getParameterTypes().length; i++) {
- if (!previous.getParameterTypes()[i].equals(current.getParameterTypes()[i])) {
- return false;
- }
- }
- return true;
+ return methods;
}
/**
diff --git a/spring-test/src/test/java/org/springframework/test/context/transaction/TransactionalTestExecutionListenerTests.java b/spring-test/src/test/java/org/springframework/test/context/transaction/TransactionalTestExecutionListenerTests.java
index 31975c73fd..0e4f7276f8 100644
--- a/spring-test/src/test/java/org/springframework/test/context/transaction/TransactionalTestExecutionListenerTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/transaction/TransactionalTestExecutionListenerTests.java
@@ -20,7 +20,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.junit.After;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -245,13 +244,11 @@ public class TransactionalTestExecutionListenerTests {
assertAfterTestMethod(AfterTransactionDeclaredViaMetaAnnotationTestCase.class);
}
- @Ignore("Disabled until @BeforeTransaction is supported on interface default methods")
@Test
public void beforeTestMethodWithBeforeTransactionDeclaredAsInterfaceDefaultMethod() throws Exception {
assertBeforeTestMethod(BeforeTransactionDeclaredAsInterfaceDefaultMethodTestCase.class);
}
- @Ignore("Disabled until @AfterTransaction is supported on interface default methods")
@Test
public void afterTestMethodWithAfterTransactionDeclaredAsInterfaceDefaultMethod() throws Exception {
assertAfterTestMethod(AfterTransactionDeclaredAsInterfaceDefaultMethodTestCase.class);
diff --git a/src/asciidoc/testing.adoc b/src/asciidoc/testing.adoc
index baa0c8a4ed..1156eb715d 100644
--- a/src/asciidoc/testing.adoc
+++ b/src/asciidoc/testing.adoc
@@ -854,9 +854,12 @@ method, potentially overriding class-level `@Rollback` or `@Commit` semantics.
+
-Indicates that the annotated `void` method should be executed __before__ a
-transaction is started for test methods configured to run within a transaction via the
-`@Transactional` annotation.
+Indicates that the annotated `void` method should be executed __before__ a transaction
+is started for test methods configured to run within a transaction via Spring's
+`@Transactional` annotation. As of Spring Framework 4.3, `@BeforeTransaction` methods
+are not required to be `public` and may be declared on Java 8 based interface default
+methods.
+
+
@@ -873,9 +876,11 @@ transaction is started for test methods configured to run within a transaction v
+
-Indicates that the annotated `void` method should be executed __after__ a
-transaction has ended for test methods configured to run within a transaction via the
-`@Transactional` annotation.
+Indicates that the annotated `void` method should be executed __after__ a transaction
+is ended for test methods configured to run within a transaction via Spring's
+`@Transactional` annotation. As of Spring Framework 4.3, `@AfterTransaction` methods
+are not required to be `public` and may be declared on Java 8 based interface default
+methods.
+
@@ -3210,12 +3215,12 @@ javadocs for `TestTransaction` for further details.
Occasionally you need to execute certain code before or after a transactional test method
but outside the transactional context -- for example, to verify the initial database state
prior to execution of your test or to verify expected transactional commit behavior after
-test execution (if the test was configured not to roll back the transaction).
+test execution (if the test was configured to commit the transaction).
`TransactionalTestExecutionListener` supports the `@BeforeTransaction` and
`@AfterTransaction` annotations exactly for such scenarios. Simply annotate any `void`
-method in your test class with one of these annotations, and the
-`TransactionalTestExecutionListener` ensures that your __before transaction method__ or
-__after transaction method__ is executed at the appropriate time.
+method in a test class or any `void` default method in a test interface with one of these
+annotations, and the `TransactionalTestExecutionListener` ensures that your __before
+transaction method__ or __after transaction method__ is executed at the appropriate time.
[TIP]
====
diff --git a/src/asciidoc/whats-new.adoc b/src/asciidoc/whats-new.adoc
index 03fa76f07d..17b4d8f4f0 100644
--- a/src/asciidoc/whats-new.adoc
+++ b/src/asciidoc/whats-new.adoc
@@ -694,8 +694,9 @@ Spring 4.3 also improves the caching abstraction as follows:
* New `SpringRunner` _alias_ for the `SpringJUnit4ClassRunner`.
* An empty declaration of `@ContextConfiguration` can now be completely omitted if default
XML files, Groovy scripts, or `@Configuration` classes are detected.
-* `@Transactional` test methods are no longer required to be `public` (in TestNG and JUnit 5).
-* `@BeforeTransaction` and `@AfterTransaction` methods are no longer required to be `public`.
+* `@Transactional` test methods are no longer required to be `public` (e.g., in TestNG and JUnit 5).
+* `@BeforeTransaction` and `@AfterTransaction` methods are no longer required to be `public`
+ and may now be declared on Java 8 based interface default methods.
* The `ApplicationContext` cache in the _Spring TestContext Framework_ is now bounded with a
default maximum size of 32 and a _least recently used_ eviction policy. The maximum size
can be configured by setting a JVM system property or Spring property called