@@ -866,19 +866,20 @@ however, these lifecycle annotations have limited usage within an actual test cl
866
866
867
867
If a method within a test class is annotated with `@PostConstruct`, that method will be
868
868
executed 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
871
871
`@PreDestroy`, that method will __never__ be executed. Within a test class it is
872
872
therefore recommended to use test lifecycle callbacks from the underlying test framework
873
873
instead of `@PostConstruct` and `@PreDestroy`.
874
874
====
875
875
876
876
877
- [[integration-testing-annotations-junit ]]
877
+ [[integration-testing-annotations-junit4 ]]
878
878
==== Spring JUnit 4 Testing Annotations
879
+
879
880
The following annotations are __only__ supported when used in conjunction with the
880
881
<<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>>.
882
883
883
884
===== @IfProfileValue
884
885
`@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.
974
975
}
975
976
----
976
977
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
+
977
1119
978
1120
[[integration-testing-annotations-meta]]
979
1121
==== Meta-Annotation Support for Testing
@@ -1000,13 +1142,17 @@ Each of the following may be used as meta-annotations in conjunction with the
1000
1142
* `@Sql`
1001
1143
* `@SqlConfig`
1002
1144
* `@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...
1010
1156
1011
1157
[source,java,indent=0]
1012
1158
[subs="verbatim,quotes"]
@@ -1024,8 +1170,8 @@ across our JUnit 4 based test suite...
1024
1170
public class UserRepositoryTests { }
1025
1171
----
1026
1172
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:
1029
1175
1030
1176
[source,java,indent=0]
1031
1177
[subs="verbatim,quotes"]
@@ -1035,25 +1181,106 @@ that centralizes the common test configuration like this:
1035
1181
@ContextConfiguration({"/app-config.xml", "/test-data-access-config.xml"})
1036
1182
@ActiveProfiles("dev")
1037
1183
@Transactional
1038
- public @interface TransactionalDevTest { }
1184
+ public @interface TransactionalDevTestConfig { }
1039
1185
----
1040
1186
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:
1043
1189
1044
1190
[source,java,indent=0]
1045
1191
[subs="verbatim,quotes"]
1046
1192
----
1047
1193
@RunWith(SpringRunner.class)
1048
- @TransactionalDevTest
1194
+ @TransactionalDevTestConfig
1049
1195
public class OrderRepositoryTests { }
1050
1196
1051
1197
@RunWith(SpringRunner.class)
1052
- @TransactionalDevTest
1198
+ @TransactionalDevTestConfig
1053
1199
public class UserRepositoryTests { }
1054
1200
----
1055
1201
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>>.
1057
1284
1058
1285
1059
1286
[[testcontext-framework]]
@@ -1066,15 +1293,17 @@ configuration__ with reasonable defaults that can be overridden through annotati
1066
1293
configuration.
1067
1294
1068
1295
In 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>>,
1078
1307
<<testcontext-fixture-di,dependency injection>>, <<testcontext-tx,transaction
1079
1308
management>>), <<testcontext-support-classes,support classes>>, and
1080
1309
<<integration-testing-annotations,annotation support>> sections.
@@ -1085,14 +1314,14 @@ management>>), <<testcontext-support-classes,support classes>>, and
1085
1314
The core of the framework consists of the `TestContextManager` class and the
1086
1315
`TestContext`, `TestExecutionListener`, and `SmartContextLoader` interfaces. A
1087
1316
`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.
1096
1325
1097
1326
===== TestContext
1098
1327
`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
3090
3319
3091
3320
[TIP]
3092
3321
====
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.
3098
3327
====
3099
3328
3100
3329
[[testcontext-tx-mgr-config]]
@@ -3112,7 +3341,7 @@ used to look up a transaction manager in the test's `ApplicationContext`.
3112
3341
[[testcontext-tx-annotation-demo]]
3113
3342
===== Demonstration of all transaction-related annotations
3114
3343
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
3116
3345
highlighting all transaction-related annotations. The example is **not** intended to
3117
3346
demonstrate best practices but rather to demonstrate how these annotations can be used.
3118
3347
Consult the <<integration-testing-annotations,annotation support>> section for further
0 commit comments