@@ -866,19 +866,20 @@ however, these lifecycle annotations have limited usage within an actual test cl
866866
867867If a method within a test class is annotated with `@PostConstruct`, that method will be
868868executed before any __before__ methods of the underlying test framework (e.g., methods
869- annotated with JUnit 4 's `@Before `), and that will apply for every test method in the test
870- class. On the other hand, if a method within a test class is annotated with
869+ annotated with JUnit Jupiter 's `@BeforeEach `), and that will apply for every test method
870+ in the test class. On the other hand, if a method within a test class is annotated with
871871`@PreDestroy`, that method will __never__ be executed. Within a test class it is
872872therefore recommended to use test lifecycle callbacks from the underlying test framework
873873instead of `@PostConstruct` and `@PreDestroy`.
874874====
875875
876876
877- [[integration-testing-annotations-junit ]]
877+ [[integration-testing-annotations-junit4 ]]
878878==== Spring JUnit 4 Testing Annotations
879+
879880The following annotations are __only__ supported when used in conjunction with the
880881<<testcontext-junit4-runner,SpringRunner>>, <<testcontext-junit4-rules,Spring's JUnit
881- rules>>, or <<testcontext-support-classes-junit4,Spring's JUnit 4 support classes>>.
882+ 4 rules>>, or <<testcontext-support-classes-junit4,Spring's JUnit 4 support classes>>.
882883
883884===== @IfProfileValue
884885`@IfProfileValue` indicates that the annotated test is enabled for a specific testing
@@ -974,6 +975,147 @@ well as any __set up__ or __tear down__ of the test fixture.
974975 }
975976----
976977
978+ [[integration-testing-annotations-junit-jupiter]]
979+ ==== Spring JUnit Jupiter Testing Annotations
980+
981+ The following annotations are __only__ supported when used in conjunction with the
982+ `SpringExtension` and JUnit Jupiter (i.e., the programming model in JUnit 5).
983+
984+ ===== @SpringJUnitConfig
985+
986+ `@SpringJUnitConfig` is a _composed annotation_ that combines
987+ `@ExtendWith(SpringExtension.class)` from JUnit Jupiter with `@ContextConfiguration` from
988+ the Spring TestContext Framework. It can be used at the class level as a drop-in
989+ replacement for `@ContextConfiguration`. With regard to configuration options, the only
990+ difference between `@ContextConfiguration` and `@SpringJUnitConfig` is that annotated
991+ classes may be declared via the `value` attribute in `@SpringJUnitConfig`.
992+
993+ [source,java,indent=0]
994+ [subs="verbatim,quotes"]
995+ ----
996+ **@SpringJUnitConfig**(TestConfig.class)
997+ class ConfigurationClassJUnitJupiterSpringTests {
998+ // class body...
999+ }
1000+ ----
1001+
1002+ [source,java,indent=0]
1003+ [subs="verbatim,quotes"]
1004+ ----
1005+ **@SpringJUnitConfig**(**locations** = "/test-config.xml")
1006+ class XmlJUnitJupiterSpringTests {
1007+ // class body...
1008+ }
1009+ ----
1010+
1011+ See <<testcontext-ctx-management>> as well as the javadocs for `@SpringJUnitConfig` and
1012+ `@ContextConfiguration` for further details.
1013+
1014+ ===== @SpringJUnitWebConfig
1015+
1016+ `@SpringJUnitWebConfig` is a _composed annotation_ that combines
1017+ `@ExtendWith(SpringExtension.class)` from JUnit Jupiter with `@ContextConfiguration` and
1018+ `@WebAppConfiguration` from the Spring TestContext Framework. It can be used at the class
1019+ level as a drop-in replacement for `@ContextConfiguration` and `@WebAppConfiguration`.
1020+ With regard to configuration options, the only difference between `@ContextConfiguration`
1021+ and `@SpringJUnitWebConfig` is that annotated classes may be declared via the `value`
1022+ attribute in `@SpringJUnitWebConfig`. In addition, the `value` attribute from
1023+ `@WebAppConfiguration` can only be overridden via the `resourcePath` attribute in
1024+ `@SpringJUnitWebConfig`.
1025+
1026+ [source,java,indent=0]
1027+ [subs="verbatim,quotes"]
1028+ ----
1029+ **@SpringJUnitWebConfig**(TestConfig.class)
1030+ class ConfigurationClassJUnitJupiterSpringWebTests {
1031+ // class body...
1032+ }
1033+ ----
1034+
1035+ [source,java,indent=0]
1036+ [subs="verbatim,quotes"]
1037+ ----
1038+ **@SpringJUnitWebConfig**(**locations** = "/test-config.xml")
1039+ class XmlJUnitJupiterSpringWebTests {
1040+ // class body...
1041+ }
1042+ ----
1043+
1044+ See <<testcontext-ctx-management>> as well as the javadocs for `@SpringJUnitWebConfig`,
1045+ `@ContextConfiguration`, and `@WebAppConfiguration` for further details.
1046+
1047+ ===== @EnabledIf
1048+
1049+ `@EnabledIf` is used to signal that the annotated JUnit Jupiter test class or test method
1050+ is _enabled_ and should be executed if the supplied `expression` evaluates to `true`.
1051+ Specifically, if the expression evaluates to `Boolean.TRUE` or a `String` equal to
1052+ `"true"` (ignoring case), the test will be __enabled__. When applied at the class level,
1053+ all test methods within that class are automatically enabled by default as well.
1054+
1055+ Expressions can be any of the following.
1056+
1057+ * Spring Expression Language (SpEL) expression – for example:
1058+ - `@EnabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")`
1059+ * Placeholder for a property available in the Spring `Environment` – for example:
1060+ - `@EnabledIf("${smoke.tests.enabled}")`
1061+ * Text literal – for example:
1062+ - `@EnabledIf("true")`
1063+
1064+ Note, however, that a text literal which is _not_ the result of dynamic resolution of a
1065+ property placeholder is of zero practical value since `@EnabledIf("false")` is equivalent
1066+ to `@Disabled` and `@EnabledIf("true")` is logically meaningless.
1067+
1068+ `@EnabledIf` may be used as a meta-annotation to create custom composed annotations. For
1069+ example, a custom `@EnabledOnMac` annotation can be created as follows.
1070+
1071+ [source,java,indent=0]
1072+ [subs="verbatim,quotes"]
1073+ ----
1074+ @Target({ ElementType.TYPE, ElementType.METHOD })
1075+ @Retention(RetentionPolicy.RUNTIME)
1076+ @EnabledIf(
1077+ expression = "#{systemProperties['os.name'].toLowerCase().contains('mac')}",
1078+ reason = "Enabled on Mac OS"
1079+ )
1080+ public @interface EnabledOnMac {}
1081+ ----
1082+
1083+ ===== @DisabledIf
1084+
1085+ `@DisabledIf` is used to signal that the annotated JUnit Jupiter test class or test
1086+ method is _disabled_ and should not be executed if the supplied `expression` evaluates to
1087+ `true`. Specifically, if the expression evaluates to `Boolean.TRUE` or a `String` equal
1088+ to `"true"` (ignoring case), the test will be __disabled__. When applied at the class
1089+ level, all test methods within that class are automatically disabled as well.
1090+
1091+ Expressions can be any of the following.
1092+
1093+ * Spring Expression Language (SpEL) expression – for example:
1094+ - `@DisabledIf("#{systemProperties['os.name'].toLowerCase().contains('mac')}")`
1095+ * Placeholder for a property available in the Spring `Environment` – for example:
1096+ - `@DisabledIf("${smoke.tests.disabled}")`
1097+ * Text literal – for example:
1098+ - `@DisabledIf("true")`
1099+
1100+ Note, however, that a text literal which is _not_ the result of dynamic resolution of a
1101+ property placeholder is of zero practical value since `@DisabledIf("true")` is
1102+ equivalent to `@Disabled` and `@DisabledIf("false")` is logically meaningless.
1103+
1104+ `@DisabledIf` may be used as a meta-annotation to create custom composed annotations. For
1105+ example, a custom `@DisabledOnMac` annotation can be created as follows.
1106+
1107+ [source,java,indent=0]
1108+ [subs="verbatim,quotes"]
1109+ ----
1110+ @Target({ ElementType.TYPE, ElementType.METHOD })
1111+ @Retention(RetentionPolicy.RUNTIME)
1112+ @DisabledIf(
1113+ expression = "#{systemProperties['os.name'].toLowerCase().contains('mac')}",
1114+ reason = "Disabled on Mac OS"
1115+ )
1116+ public @interface DisabledOnMac {}
1117+ ----
1118+
9771119
9781120[[integration-testing-annotations-meta]]
9791121==== Meta-Annotation Support for Testing
@@ -1000,13 +1142,17 @@ Each of the following may be used as meta-annotations in conjunction with the
10001142* `@Sql`
10011143* `@SqlConfig`
10021144* `@SqlGroup`
1003- * `@Repeat`
1004- * `@Timed`
1005- * `@IfProfileValue`
1006- * `@ProfileValueSourceConfiguration`
1007-
1008- For example, if we discover that we are repeating the following configuration
1009- across our JUnit 4 based test suite...
1145+ * `@Repeat` _(JUnit 4)_
1146+ * `@Timed` _(JUnit 4)_
1147+ * `@IfProfileValue` _(JUnit 4)_
1148+ * `@ProfileValueSourceConfiguration` _(JUnit 4)_
1149+ * `@SpringJUnitConfig` _(JUnit Jupiter)_
1150+ * `@SpringJUnitWebConfig` _(JUnit Jupiter)_
1151+ * `@EnabledIf` _(JUnit Jupiter)_
1152+ * `@DisabledIf` _(JUnit Jupiter)_
1153+
1154+ For example, if we discover that we are repeating the following configuration across our
1155+ _JUnit 4_ based test suite...
10101156
10111157[source,java,indent=0]
10121158[subs="verbatim,quotes"]
@@ -1024,8 +1170,8 @@ across our JUnit 4 based test suite...
10241170 public class UserRepositoryTests { }
10251171----
10261172
1027- We can reduce the above duplication by introducing a custom _composed annotation_
1028- that centralizes the common test configuration like this:
1173+ We can reduce the above duplication by introducing a custom _composed annotation_ that
1174+ centralizes the common test configuration for Spring like this:
10291175
10301176[source,java,indent=0]
10311177[subs="verbatim,quotes"]
@@ -1035,25 +1181,106 @@ that centralizes the common test configuration like this:
10351181 @ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
10361182 @ActiveProfiles("dev")
10371183 @Transactional
1038- public @interface TransactionalDevTest { }
1184+ public @interface TransactionalDevTestConfig { }
10391185----
10401186
1041- Then we can use our custom `@TransactionalDevTest ` annotation to simplify the
1042- configuration of individual test classes as follows:
1187+ Then we can use our custom `@TransactionalDevTestConfig ` annotation to simplify the
1188+ configuration of individual JUnit 4 based test classes as follows:
10431189
10441190[source,java,indent=0]
10451191[subs="verbatim,quotes"]
10461192----
10471193 @RunWith(SpringRunner.class)
1048- @TransactionalDevTest
1194+ @TransactionalDevTestConfig
10491195 public class OrderRepositoryTests { }
10501196
10511197 @RunWith(SpringRunner.class)
1052- @TransactionalDevTest
1198+ @TransactionalDevTestConfig
10531199 public class UserRepositoryTests { }
10541200----
10551201
1056- For further details, consult the <<core.adoc#annotation-programming-model,Spring Annotation Programming Model>>.
1202+ If we are writing tests using JUnit Jupiter, we can reduce code duplication even further
1203+ since annotations in JUnit 5 can also be used as meta-annotations. For example, if we
1204+ discover that we are repeating the following configuration across our JUnit Jupiter based
1205+ test suite...
1206+
1207+ [source,java,indent=0]
1208+ [subs="verbatim,quotes"]
1209+ ----
1210+ @ExtendWith(SpringExtension.class)
1211+ @ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
1212+ @ActiveProfiles("dev")
1213+ @Transactional
1214+ class OrderRepositoryTests { }
1215+
1216+ @ExtendWith(SpringExtension.class)
1217+ @ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
1218+ @ActiveProfiles("dev")
1219+ @Transactional
1220+ class UserRepositoryTests { }
1221+ ----
1222+
1223+ We can reduce the above duplication by introducing a custom _composed annotation_
1224+ that centralizes the common test configuration for Spring and JUnit Jupiter like this:
1225+
1226+ [source,java,indent=0]
1227+ [subs="verbatim,quotes"]
1228+ ----
1229+ @Target(ElementType.TYPE)
1230+ @Retention(RetentionPolicy.RUNTIME)
1231+ @ExtendWith(SpringExtension.class)
1232+ @ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
1233+ @ActiveProfiles("dev")
1234+ @Transactional
1235+ public @interface TransactionalDevTestConfig { }
1236+ ----
1237+
1238+ Then we can use our custom `@TransactionalDevTestConfig` annotation to simplify the
1239+ configuration of individual JUnit Jupiter based test classes as follows:
1240+
1241+ [source,java,indent=0]
1242+ [subs="verbatim,quotes"]
1243+ ----
1244+ @TransactionalDevTestConfig
1245+ class OrderRepositoryTests { }
1246+
1247+ @TransactionalDevTestConfig
1248+ class UserRepositoryTests { }
1249+ ----
1250+
1251+ Since JUnit Jupiter supports the use of `@Test`, `@RepeatedTest`, `ParameterizedTest`,
1252+ etc. as meta-annotations, it is also possible to create custom composed annotations at
1253+ the test method level. For example, if we wish to create a _composed annotation_ that
1254+ combines the `@Test` and `@Tag` annotations from JUnit Jupiter with the `@Transactional`
1255+ annotation from Spring, we could create an `@TransactionalIntegrationTest` annotation as
1256+ follows.
1257+
1258+ [source,java,indent=0]
1259+ [subs="verbatim,quotes"]
1260+ ----
1261+ @Target(ElementType.METHOD)
1262+ @Retention(RetentionPolicy.RUNTIME)
1263+ @Transactional
1264+ @Tag("integration-test") // org.junit.jupiter.api.Tag
1265+ @Test // org.junit.jupiter.api.Test
1266+ public @interface TransactionalIntegrationTest { }
1267+ ----
1268+
1269+ Then we can use our custom `@TransactionalIntegrationTest` annotation to simplify the
1270+ configuration of individual JUnit Jupiter based test methods as follows:
1271+
1272+ [source,java,indent=0]
1273+ [subs="verbatim,quotes"]
1274+ ----
1275+ @TransactionalIntegrationTest
1276+ void saveOrder() { }
1277+
1278+ @TransactionalIntegrationTest
1279+ void deleteOrder() { }
1280+ ----
1281+
1282+ For further details, consult the <<core.adoc#annotation-programming-model,Spring
1283+ Annotation Programming Model>>.
10571284
10581285
10591286[[testcontext-framework]]
@@ -1066,15 +1293,17 @@ configuration__ with reasonable defaults that can be overridden through annotati
10661293configuration.
10671294
10681295In addition to generic testing infrastructure, the TestContext framework provides
1069- explicit support for JUnit 4 and TestNG in the form of `abstract` support classes. For
1070- JUnit 4, Spring also provides a custom JUnit `Runner` and custom JUnit `Rules` that allow
1071- one to write so-called __POJO test classes__. POJO test classes are not required to
1072- extend a particular class hierarchy.
1073-
1074- The following section provides an overview of the internals of the TestContext
1075- framework. If you are only interested in _using_ the framework and not necessarily
1076- interested in _extending_ it with your own custom listeners or custom loaders, feel free
1077- to go directly to the configuration (<<testcontext-ctx-management,context management>>,
1296+ explicit support for JUnit 4, JUnit Jupiter (a.k.a., JUnit 5), and TestNG. For JUnit 4
1297+ and TestNG, Spring provides `abstract` support classes. Furthermore, Spring provides a
1298+ custom JUnit `Runner` and custom JUnit `Rules` for _JUnit 4_ as well as a custom
1299+ `Extension` for _JUnit Jupiter_ that allow one to write so-called __POJO test classes__.
1300+ POJO test classes are not required to extend a particular class hierarchy such as the
1301+ `abstract` support classes.
1302+
1303+ The following section provides an overview of the internals of the TestContext framework.
1304+ If you are only interested in _using_ the framework and not necessarily interested in
1305+ _extending_ it with your own custom listeners or custom loaders, feel free to go directly
1306+ to the configuration (<<testcontext-ctx-management,context management>>,
10781307<<testcontext-fixture-di,dependency injection>>, <<testcontext-tx,transaction
10791308management>>), <<testcontext-support-classes,support classes>>, and
10801309<<integration-testing-annotations,annotation support>> sections.
@@ -1085,14 +1314,14 @@ management>>), <<testcontext-support-classes,support classes>>, and
10851314The core of the framework consists of the `TestContextManager` class and the
10861315`TestContext`, `TestExecutionListener`, and `SmartContextLoader` interfaces. A
10871316`TestContextManager` is created per test class (e.g., for the execution of all test
1088- methods within a single test class in JUnit 4 ). The `TestContextManager` in turn manages a
1089- `TestContext` that holds the context of the current test. The `TestContextManager` also
1090- updates the state of the `TestContext` as the test progresses and delegates to
1091- `TestExecutionListener` implementations, which instrument the actual test execution by
1092- providing dependency injection, managing transactions, and so on. A `SmartContextLoader`
1093- is responsible for loading an `ApplicationContext` for a given test class. Consult the
1094- javadocs and the Spring test suite for further information and examples of various
1095- implementations.
1317+ methods within a single test class in JUnit Jupiter ). The `TestContextManager` in turn
1318+ manages a `TestContext` that holds the context of the current test. The
1319+ `TestContextManager` also updates the state of the `TestContext` as the test progresses
1320+ and delegates to `TestExecutionListener` implementations, which instrument the actual
1321+ test execution by providing dependency injection, managing transactions, and so on. A
1322+ `SmartContextLoader` is responsible for loading an `ApplicationContext` for a given test
1323+ class. Consult the javadocs and the Spring test suite for further information and
1324+ examples of various implementations.
10961325
10971326===== TestContext
10981327`TestContext` encapsulates the context in which a test is executed, agnostic of the
@@ -3090,11 +3319,11 @@ transaction method__ or __after transaction method__ is executed at the appropri
30903319
30913320[TIP]
30923321====
3093- Any __before methods__ (such as methods annotated with JUnit 4 's `@Before `) and any __after
3094- methods__ (such as methods annotated with JUnit 4 's `@After `) are executed __within__ a
3095- transaction. In addition, methods annotated with `@BeforeTransaction` or
3096- `@AfterTransaction` are naturally not executed for test methods that are not configured
3097- to run within a transaction.
3322+ Any __before methods__ (such as methods annotated with JUnit Jupiter 's `@BeforeEach `) and
3323+ any __after methods__ (such as methods annotated with JUnit Jupiter 's `@AfterEach `) are
3324+ executed __within__ a transaction. In addition, methods annotated with
3325+ `@BeforeTransaction` or `@ AfterTransaction` are naturally not executed for test methods
3326+ that are not configured to run within a transaction.
30983327====
30993328
31003329[[testcontext-tx-mgr-config]]
@@ -3112,7 +3341,7 @@ used to look up a transaction manager in the test's `ApplicationContext`.
31123341[[testcontext-tx-annotation-demo]]
31133342===== Demonstration of all transaction-related annotations
31143343
3115- The following JUnit 4 based example displays a fictitious integration testing scenario
3344+ The following JUnit 4 based example displays a _fictitious_ integration testing scenario
31163345highlighting all transaction-related annotations. The example is **not** intended to
31173346demonstrate best practices but rather to demonstrate how these annotations can be used.
31183347Consult the <<integration-testing-annotations,annotation support>> section for further
0 commit comments