From ef34464c94e29beb2e7881d16087abd908041498 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Sat, 26 Apr 2025 09:33:13 +0200 Subject: [PATCH] Restructure TestContext framework support sections This commit moves the JUnit Jupiter section above the JUnit 4 section and groups all JUnit 4 sections under a new "JUnit 4 Support" heading. --- .../annotations/integration-junit4.adoc | 5 +- .../support-classes.adoc | 373 +++++++++--------- 2 files changed, 198 insertions(+), 180 deletions(-) diff --git a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit4.adoc b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit4.adoc index 17fdf5c9bef..fdc6470f968 100644 --- a/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit4.adoc +++ b/framework-docs/modules/ROOT/pages/testing/annotations/integration-junit4.adoc @@ -2,8 +2,9 @@ = Spring JUnit 4 Testing Annotations The following annotations are supported only when used in conjunction with the -xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-runner[SpringRunner], xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-rules[Spring's JUnit 4 rules] -, or xref:testing/testcontext-framework/support-classes.adoc#testcontext-support-classes-junit4[Spring's JUnit 4 support classes]: +xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-runner[SpringRunner], +xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-rules[Spring's JUnit 4 rules], or +xref:testing/testcontext-framework/support-classes.adoc#testcontext-support-classes-junit4[Spring's JUnit 4 support classes]: * xref:testing/annotations/integration-junit4.adoc#integration-testing-annotations-junit4-ifprofilevalue[`@IfProfileValue`] * xref:testing/annotations/integration-junit4.adoc#integration-testing-annotations-junit4-profilevaluesourceconfiguration[`@ProfileValueSourceConfiguration`] diff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/support-classes.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/support-classes.adoc index 1ee5856ecfd..a7798005873 100644 --- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/support-classes.adoc +++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/support-classes.adoc @@ -1,166 +1,9 @@ [[testcontext-support-classes]] = TestContext Framework Support Classes -This section describes the various classes that support the Spring TestContext Framework. +This section describes the various classes that support the Spring TestContext Framework +in JUnit and TestNG. -[[testcontext-junit4-runner]] -== Spring JUnit 4 Runner - -The Spring TestContext Framework offers full integration with JUnit 4 through a custom -runner (supported on JUnit 4.12 or higher). By annotating test classes with -`@RunWith(SpringJUnit4ClassRunner.class)` or the shorter `@RunWith(SpringRunner.class)` -variant, developers can implement standard JUnit 4-based unit and integration tests and -simultaneously reap the benefits of the TestContext framework, such as support for -loading application contexts, dependency injection of test instances, transactional test -method execution, and so on. If you want to use the Spring TestContext Framework with an -alternative runner (such as JUnit 4's `Parameterized` runner) or third-party runners -(such as the `MockitoJUnitRunner`), you can, optionally, use -xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-rules[Spring's support for JUnit rules] instead. - -The following code listing shows the minimal requirements for configuring a test class to -run with the custom Spring `Runner`: - -[tabs] -====== -Java:: -+ -[source,java,indent=0,subs="verbatim,quotes"] ----- - @RunWith(SpringRunner.class) - @TestExecutionListeners({}) - public class SimpleTest { - - @Test - public void testMethod() { - // test logic... - } - } ----- - -Kotlin:: -+ -[source,kotlin,indent=0,subs="verbatim,quotes"] ----- - @RunWith(SpringRunner::class) - @TestExecutionListeners - class SimpleTest { - - @Test - fun testMethod() { - // test logic... - } - } ----- -====== - -In the preceding example, `@TestExecutionListeners` is configured with an empty list, to -disable the default listeners, which otherwise would require an `ApplicationContext` to -be configured through `@ContextConfiguration`. - -[[testcontext-junit4-rules]] -== Spring JUnit 4 Rules - -The `org.springframework.test.context.junit4.rules` package provides the following JUnit -4 rules (supported on JUnit 4.12 or higher): - -* `SpringClassRule` -* `SpringMethodRule` - -`SpringClassRule` is a JUnit `TestRule` that supports class-level features of the Spring -TestContext Framework, whereas `SpringMethodRule` is a JUnit `MethodRule` that supports -instance-level and method-level features of the Spring TestContext Framework. - -In contrast to the `SpringRunner`, Spring's rule-based JUnit support has the advantage of -being independent of any `org.junit.runner.Runner` implementation and can, therefore, be -combined with existing alternative runners (such as JUnit 4's `Parameterized`) or -third-party runners (such as the `MockitoJUnitRunner`). - -To support the full functionality of the TestContext framework, you must combine a -`SpringClassRule` with a `SpringMethodRule`. The following example shows the proper way -to declare these rules in an integration test: - -[tabs] -====== -Java:: -+ -[source,java,indent=0,subs="verbatim,quotes"] ----- - // Optionally specify a non-Spring Runner via @RunWith(...) - @ContextConfiguration - public class IntegrationTest { - - @ClassRule - public static final SpringClassRule springClassRule = new SpringClassRule(); - - @Rule - public final SpringMethodRule springMethodRule = new SpringMethodRule(); - - @Test - public void testMethod() { - // test logic... - } - } ----- - -Kotlin:: -+ -[source,kotlin,indent=0,subs="verbatim,quotes"] ----- - // Optionally specify a non-Spring Runner via @RunWith(...) - @ContextConfiguration - class IntegrationTest { - - @Rule - val springMethodRule = SpringMethodRule() - - @Test - fun testMethod() { - // test logic... - } - - companion object { - @ClassRule - val springClassRule = SpringClassRule() - } - } ----- -====== - -[[testcontext-support-classes-junit4]] -== JUnit 4 Support Classes - -The `org.springframework.test.context.junit4` package provides the following support -classes for JUnit 4-based test cases (supported on JUnit 4.12 or higher): - -* `AbstractJUnit4SpringContextTests` -* `AbstractTransactionalJUnit4SpringContextTests` - -`AbstractJUnit4SpringContextTests` is an abstract base test class that integrates the -Spring TestContext Framework with explicit `ApplicationContext` testing support in a -JUnit 4 environment. When you extend `AbstractJUnit4SpringContextTests`, you can access a -`protected` `applicationContext` instance variable that you can use to perform explicit -bean lookups or to test the state of the context as a whole. - -`AbstractTransactionalJUnit4SpringContextTests` is an abstract transactional extension of -`AbstractJUnit4SpringContextTests` that adds some convenience functionality for JDBC -access. This class expects a `javax.sql.DataSource` bean and a -`PlatformTransactionManager` bean to be defined in the `ApplicationContext`. When you -extend `AbstractTransactionalJUnit4SpringContextTests`, you can access a `protected` -`jdbcTemplate` instance variable that you can use to run SQL statements to query the -database. You can use such queries to confirm database state both before and after -running database-related application code, and Spring ensures that such queries run in -the scope of the same transaction as the application code. When used in conjunction with -an ORM tool, be sure to avoid xref:testing/testcontext-framework/tx.adoc#testcontext-tx-false-positives[false positives]. -As mentioned in xref:testing/support-jdbc.adoc[JDBC Testing Support], -`AbstractTransactionalJUnit4SpringContextTests` also provides convenience methods that -delegate to methods in `JdbcTestUtils` by using the aforementioned `jdbcTemplate`. -Furthermore, `AbstractTransactionalJUnit4SpringContextTests` provides an -`executeSqlScript(..)` method for running SQL scripts against the configured `DataSource`. - -TIP: These classes are a convenience for extension. If you do not want your test classes -to be tied to a Spring-specific class hierarchy, you can configure your own custom test -classes by using `@RunWith(SpringRunner.class)` or xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-rules[Spring's JUnit rules] -. [[testcontext-junit-jupiter-extension]] == SpringExtension for JUnit Jupiter @@ -177,14 +20,17 @@ following features above and beyond the feature set that Spring supports for JUn TestNG: * Dependency injection for test constructors, test methods, and test lifecycle callback - methods. See xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[Dependency Injection with the `SpringExtension`] for further details. + methods. See xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit-jupiter-di[Dependency + Injection with the `SpringExtension`] for further details. * Powerful support for link:https://junit.org/junit5/docs/current/user-guide/#extensions-conditions[conditional test execution] based on SpEL expressions, environment variables, system properties, and so on. See the documentation for `@EnabledIf` and `@DisabledIf` in - xref:testing/annotations/integration-junit-jupiter.adoc[Spring JUnit Jupiter Testing Annotations] for further details and examples. + xref:testing/annotations/integration-junit-jupiter.adoc[Spring JUnit Jupiter Testing Annotations] + for further details and examples. * Custom composed annotations that combine annotations from Spring and JUnit Jupiter. See the `@TransactionalDevTestConfig` and `@TransactionalIntegrationTest` examples in - xref:testing/annotations/integration-meta.adoc[Meta-Annotation Support for Testing] for further details. + xref:testing/annotations/integration-meta.adoc[Meta-Annotation Support for Testing] for + further details. The following code listing shows how to configure a test class to use the `SpringExtension` in conjunction with `@ContextConfiguration`: @@ -307,7 +153,8 @@ Kotlin:: ====== See the documentation for `@SpringJUnitConfig` and `@SpringJUnitWebConfig` in -xref:testing/annotations/integration-junit-jupiter.adoc[Spring JUnit Jupiter Testing Annotations] for further details. +xref:testing/annotations/integration-junit-jupiter.adoc[Spring JUnit Jupiter Testing Annotations] +for further details. [[testcontext-junit-jupiter-di]] === Dependency Injection with the `SpringExtension` @@ -318,10 +165,9 @@ extension API from JUnit Jupiter, which lets Spring provide dependency injection constructors, test methods, and test lifecycle callback methods. Specifically, the `SpringExtension` can inject dependencies from the test's -`ApplicationContext` into test constructors and methods that are annotated with -Spring's `@BeforeTransaction` and `@AfterTransaction` or JUnit's `@BeforeAll`, -`@AfterAll`, `@BeforeEach`, `@AfterEach`, `@Test`, `@RepeatedTest`, `@ParameterizedTest`, -and others. +`ApplicationContext` into test constructors and methods that are annotated with Spring's +`@BeforeTransaction` and `@AfterTransaction` or JUnit's `@BeforeAll`, `@AfterAll`, +`@BeforeEach`, `@AfterEach`, `@Test`, `@RepeatedTest`, `@ParameterizedTest`, and others. [[testcontext-junit-jupiter-di-constructor]] @@ -341,8 +187,9 @@ autowirable if one of the following conditions is met (in order of precedence). attribute set to `ALL`. * The default _test constructor autowire mode_ has been changed to `ALL`. -See xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-testconstructor[`@TestConstructor`] for details on the use of -`@TestConstructor` and how to change the global _test constructor autowire mode_. +See xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-testconstructor[`@TestConstructor`] +for details on the use of `@TestConstructor` and how to change the global _test +constructor autowire mode_. WARNING: If the constructor for a test class is considered to be _autowirable_, Spring assumes the responsibility for resolving arguments for all parameters in the constructor. @@ -407,8 +254,9 @@ Kotlin:: Note that this feature lets test dependencies be `final` and therefore immutable. If the `spring.test.constructor.autowire.mode` property is to `all` (see -xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-testconstructor[`@TestConstructor`]), we can omit the declaration of -`@Autowired` on the constructor in the previous example, resulting in the following. +xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-testconstructor[`@TestConstructor`]), +we can omit the declaration of `@Autowired` on the constructor in the previous example, +resulting in the following. [tabs] ====== @@ -553,17 +401,19 @@ honor `@NestedTestConfiguration` semantics. In order to allow development teams to change the default to `OVERRIDE` – for example, for compatibility with Spring Framework 5.0 through 5.2 – the default mode can be changed globally via a JVM system property or a `spring.properties` file in the root of the -classpath. See the xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-nestedtestconfiguration["Changing the default enclosing configuration inheritance mode"] - note for details. +classpath. See the +xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-nestedtestconfiguration["Changing the default enclosing configuration inheritance mode"] +note for details. Although the following "Hello World" example is very simplistic, it shows how to declare common configuration on a top-level class that is inherited by its `@Nested` test classes. In this particular example, only the `TestConfig` configuration class is inherited. Each nested test class provides its own set of active profiles, resulting in a distinct `ApplicationContext` for each nested test class (see -xref:testing/testcontext-framework/ctx-management/caching.adoc[Context Caching] for details). Consult the list of -xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-nestedtestconfiguration[supported annotations] to see -which annotations can be inherited in `@Nested` test classes. +xref:testing/testcontext-framework/ctx-management/caching.adoc[Context Caching] for details). +Consult the list of +xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-nestedtestconfiguration[supported annotations] +to see which annotations can be inherited in `@Nested` test classes. [tabs] ====== @@ -626,8 +476,174 @@ Kotlin:: ---- ====== + +[[testcontext-junit4-support]] +== JUnit 4 Support + +[[testcontext-junit4-runner]] +=== Spring JUnit 4 Runner + +The Spring TestContext Framework offers full integration with JUnit 4 through a custom +runner (supported on JUnit 4.12 or higher). By annotating test classes with +`@RunWith(SpringJUnit4ClassRunner.class)` or the shorter `@RunWith(SpringRunner.class)` +variant, developers can implement standard JUnit 4-based unit and integration tests and +simultaneously reap the benefits of the TestContext framework, such as support for +loading application contexts, dependency injection of test instances, transactional test +method execution, and so on. If you want to use the Spring TestContext Framework with an +alternative runner (such as JUnit 4's `Parameterized` runner) or third-party runners +(such as the `MockitoJUnitRunner`), you can, optionally, use +xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-rules[Spring's support for JUnit rules] +instead. + +The following code listing shows the minimal requirements for configuring a test class to +run with the custom Spring `Runner`: + +[tabs] +====== +Java:: ++ +[source,java,indent=0,subs="verbatim,quotes"] +---- + @RunWith(SpringRunner.class) + @TestExecutionListeners({}) + public class SimpleTest { + + @Test + public void testMethod() { + // test logic... + } + } +---- + +Kotlin:: ++ +[source,kotlin,indent=0,subs="verbatim,quotes"] +---- + @RunWith(SpringRunner::class) + @TestExecutionListeners + class SimpleTest { + + @Test + fun testMethod() { + // test logic... + } + } +---- +====== + +In the preceding example, `@TestExecutionListeners` is configured with an empty list, to +disable the default listeners, which otherwise would require an `ApplicationContext` to +be configured through `@ContextConfiguration`. + +[[testcontext-junit4-rules]] +=== Spring JUnit 4 Rules + +The `org.springframework.test.context.junit4.rules` package provides the following JUnit +4 rules (supported on JUnit 4.12 or higher): + +* `SpringClassRule` +* `SpringMethodRule` + +`SpringClassRule` is a JUnit `TestRule` that supports class-level features of the Spring +TestContext Framework, whereas `SpringMethodRule` is a JUnit `MethodRule` that supports +instance-level and method-level features of the Spring TestContext Framework. + +In contrast to the `SpringRunner`, Spring's rule-based JUnit support has the advantage of +being independent of any `org.junit.runner.Runner` implementation and can, therefore, be +combined with existing alternative runners (such as JUnit 4's `Parameterized`) or +third-party runners (such as the `MockitoJUnitRunner`). + +To support the full functionality of the TestContext framework, you must combine a +`SpringClassRule` with a `SpringMethodRule`. The following example shows the proper way +to declare these rules in an integration test: + +[tabs] +====== +Java:: ++ +[source,java,indent=0,subs="verbatim,quotes"] +---- + // Optionally specify a non-Spring Runner via @RunWith(...) + @ContextConfiguration + public class IntegrationTest { + + @ClassRule + public static final SpringClassRule springClassRule = new SpringClassRule(); + + @Rule + public final SpringMethodRule springMethodRule = new SpringMethodRule(); + + @Test + public void testMethod() { + // test logic... + } + } +---- + +Kotlin:: ++ +[source,kotlin,indent=0,subs="verbatim,quotes"] +---- + // Optionally specify a non-Spring Runner via @RunWith(...) + @ContextConfiguration + class IntegrationTest { + + @Rule + val springMethodRule = SpringMethodRule() + + @Test + fun testMethod() { + // test logic... + } + + companion object { + @ClassRule + val springClassRule = SpringClassRule() + } + } +---- +====== + +[[testcontext-support-classes-junit4]] +=== JUnit 4 Base Classes + +The `org.springframework.test.context.junit4` package provides the following support +classes for JUnit 4-based test cases (supported on JUnit 4.12 or higher): + +* `AbstractJUnit4SpringContextTests` +* `AbstractTransactionalJUnit4SpringContextTests` + +`AbstractJUnit4SpringContextTests` is an abstract base test class that integrates the +Spring TestContext Framework with explicit `ApplicationContext` testing support in a +JUnit 4 environment. When you extend `AbstractJUnit4SpringContextTests`, you can access a +`protected` `applicationContext` instance variable that you can use to perform explicit +bean lookups or to test the state of the context as a whole. + +`AbstractTransactionalJUnit4SpringContextTests` is an abstract transactional extension of +`AbstractJUnit4SpringContextTests` that adds some convenience functionality for JDBC +access. This class expects a `javax.sql.DataSource` bean and a +`PlatformTransactionManager` bean to be defined in the `ApplicationContext`. When you +extend `AbstractTransactionalJUnit4SpringContextTests`, you can access a `protected` +`jdbcTemplate` instance variable that you can use to run SQL statements to query the +database. You can use such queries to confirm database state both before and after +running database-related application code, and Spring ensures that such queries run in +the scope of the same transaction as the application code. When used in conjunction with +an ORM tool, be sure to avoid +xref:testing/testcontext-framework/tx.adoc#testcontext-tx-false-positives[false positives]. +As mentioned in xref:testing/support-jdbc.adoc[JDBC Testing Support], +`AbstractTransactionalJUnit4SpringContextTests` also provides convenience methods that +delegate to methods in `JdbcTestUtils` by using the aforementioned `jdbcTemplate`. +Furthermore, `AbstractTransactionalJUnit4SpringContextTests` provides an +`executeSqlScript(..)` method for running SQL scripts against the configured `DataSource`. + +TIP: These classes are a convenience for extension. If you do not want your test classes +to be tied to a Spring-specific class hierarchy, you can configure your own custom test +classes by using `@RunWith(SpringRunner.class)` or +xref:testing/testcontext-framework/support-classes.adoc#testcontext-junit4-rules[Spring's JUnit rules]. + + [[testcontext-support-classes-testng]] -== TestNG Support Classes +== TestNG Support The `org.springframework.test.context.testng` package provides the following support classes for TestNG based test cases: @@ -650,7 +666,8 @@ extend `AbstractTransactionalTestNGSpringContextTests`, you can access a `protec database. You can use such queries to confirm database state both before and after running database-related application code, and Spring ensures that such queries run in the scope of the same transaction as the application code. When used in conjunction with -an ORM tool, be sure to avoid xref:testing/testcontext-framework/tx.adoc#testcontext-tx-false-positives[false positives]. +an ORM tool, be sure to avoid +xref:testing/testcontext-framework/tx.adoc#testcontext-tx-false-positives[false positives]. As mentioned in xref:testing/support-jdbc.adoc[JDBC Testing Support], `AbstractTransactionalTestNGSpringContextTests` also provides convenience methods that delegate to methods in `JdbcTestUtils` by using the aforementioned `jdbcTemplate`.