Skip to content

Commit 8c9d42f

Browse files
committed
Document SpringExtension for JUnit Jupiter in reference manual
Issue: SPR-14524
1 parent 492c469 commit 8c9d42f

File tree

1 file changed

+195
-1
lines changed

1 file changed

+195
-1
lines changed

src/docs/asciidoc/testing.adoc

Lines changed: 195 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,8 @@ well as any __set up__ or __tear down__ of the test fixture.
979979
==== Spring JUnit Jupiter Testing Annotations
980980

981981
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).
982+
<<testcontext-junit-jupiter-extension,`SpringExtension`>> and JUnit Jupiter (i.e., the
983+
programming model in JUnit 5).
983984

984985
===== @SpringJUnitConfig
985986

@@ -3912,6 +3913,199 @@ JUnit rules>>.
39123913
====
39133914

39143915

3916+
[[testcontext-junit-jupiter-extension]]
3917+
===== SpringExtension for JUnit Jupiter
3918+
3919+
The __Spring TestContext Framework__ offers full integration with the _JUnit Jupiter_
3920+
testing framework introduced in JUnit 5. By annotating test classes with
3921+
`@ExtendWith(SpringExtension.class)`, developers can implement standard JUnit Jupiter
3922+
based unit and integration tests and simultaneously reap the benefits of the TestContext
3923+
framework such as support for loading application contexts, dependency injection of test
3924+
instances, transactional test method execution, and so on.
3925+
3926+
Furthermore, thanks to the rich extension API in JUnit Jupiter, Spring is able to provide
3927+
the following features above and beyond the feature set that Spring supports for JUnit 4
3928+
and TestNG.
3929+
3930+
* Dependency injection for test constructors, test methods, and test lifecycle callback
3931+
methods
3932+
- See <<testcontext-junit-jupiter-di>> for further details.
3933+
* Powerful support for link:http://junit.org/junit5/docs/current/user-guide/#extensions-conditions[_conditional test execution_]
3934+
based on SpEL expressions, environment variables, system properties, etc.
3935+
- See the documentation for `@EnabledIf` and `@DisabledIf` in
3936+
<<integration-testing-annotations-junit-jupiter>> for further details and examples.
3937+
* Custom _composed annotations_ that combine annotations from Spring **and** JUnit
3938+
Jupiter.
3939+
- See the `@TransactionalDevTestConfig` and `@TransactionalIntegrationTest` examples in
3940+
<<integration-testing-annotations-meta>> for further details.
3941+
3942+
The following code listing demonstrates how to configure a test class to use the
3943+
`SpringExtension` in conjunction with `@ContextConfiguration`.
3944+
3945+
[source,java,indent=0]
3946+
[subs="verbatim,quotes"]
3947+
----
3948+
// Instructs JUnit Jupiter to extend the test with Spring support.
3949+
@ExtendWith(SpringExtension.class)
3950+
// Instructs Spring to load an ApplicationContext from TestConfig.class
3951+
@ContextConfiguration(classes = TestConfig.class)
3952+
class SimpleTests {
3953+
3954+
@Test
3955+
void testMethod() {
3956+
// execute test logic...
3957+
}
3958+
}
3959+
----
3960+
3961+
Since annotations in JUnit 5 can also be used as meta-annotations, Spring is able to
3962+
provide `@SpringJUnitConfig` and `@SpringJUnitWebConfig` __composed annotations__ to
3963+
simplify the configuration of the test `ApplicationContext` and JUnit Jupiter.
3964+
3965+
For example, the following example uses `@SpringJUnitConfig` to reduce the amount of
3966+
configuration used in the previous example.
3967+
3968+
[source,java,indent=0]
3969+
[subs="verbatim,quotes"]
3970+
----
3971+
// Instructs Spring to register the SpringExtension with JUnit
3972+
// Jupiter and load an ApplicationContext from TestConfig.class
3973+
@SpringJUnitConfig(TestConfig.class)
3974+
class SimpleTests {
3975+
3976+
@Test
3977+
void testMethod() {
3978+
// execute test logic...
3979+
}
3980+
}
3981+
----
3982+
3983+
Similarly, the following example uses `@SpringJUnitWebConfig` to create a
3984+
`WebApplicationContext` for use with JUnit Jupiter.
3985+
3986+
[source,java,indent=0]
3987+
[subs="verbatim,quotes"]
3988+
----
3989+
// Instructs Spring to register the SpringExtension with JUnit
3990+
// Jupiter and load a WebApplicationContext from TestWebConfig.class
3991+
@SpringJUnitWebConfig(TestWebConfig.class)
3992+
class SimpleWebTests {
3993+
3994+
@Test
3995+
void testMethod() {
3996+
// execute test logic...
3997+
}
3998+
}
3999+
----
4000+
4001+
See the documentation for `@SpringJUnitConfig` and `@SpringJUnitWebConfig` in
4002+
<<integration-testing-annotations-junit-jupiter>> for further details.
4003+
4004+
4005+
[[testcontext-junit-jupiter-di]]
4006+
===== Dependency Injection with the SpringExtension
4007+
4008+
The `SpringExtension` implements the
4009+
link:http://junit.org/junit5/docs/current/user-guide/#extensions-parameter-resolution[`ParameterResolver`]
4010+
extension API from JUnit Jupiter which allows Spring to provide dependency injection for
4011+
test constructors, test methods, and test lifecycle callback methods.
4012+
4013+
Specifically, the `SpringExtension` is able to inject dependencies from the test's
4014+
`ApplicationContext` into test constructors and methods annotated with `@BeforeAll`,
4015+
`@AfterAll`, `@BeforeEach`, `@AfterEach`, `@Test`, `@RepeatedTest`, `@ParameterizedTest`,
4016+
etc.
4017+
4018+
[[testcontext-junit-jupiter-di-constructor]]
4019+
====== Constructor Injection
4020+
4021+
If a parameter in a constructor for a JUnit Jupiter test class is of type
4022+
`ApplicationContext` (or a sub-type thereof) or is annotated or meta-annotated with
4023+
`@Autowired`, `@Qualifier`, or `@Value`, Spring will inject the value for that specific
4024+
parameter with the corresponding bean from the test's `ApplicationContext`. A test
4025+
constructor can also be directly annotated with `@Autowired` if all of the parameters
4026+
should be supplied by Spring.
4027+
4028+
[WARNING]
4029+
====
4030+
If the constructor for a test class is itself annotated with `@Autowired`, Spring will
4031+
assume the responsibility for resolving **all** parameters in the constructor.
4032+
Consequently, no other `ParameterResolver` registered with JUnit Jupiter will be able to
4033+
resolve parameters for such a constructor.
4034+
====
4035+
4036+
In the following example, Spring will inject the `OrderService` bean from the
4037+
`ApplicationContext` loaded from `TestConfig.class` into the
4038+
`OrderServiceIntegrationTests` constructor. Note as well that this feature allows test
4039+
dependencies to be `final` and therefore _immutable_.
4040+
4041+
[source,java,indent=0]
4042+
[subs="verbatim,quotes"]
4043+
----
4044+
@SpringJUnitConfig(TestConfig.class)
4045+
class OrderServiceIntegrationTests {
4046+
4047+
private final OrderService orderService;
4048+
4049+
@Autowired
4050+
OrderServiceIntegrationTests(OrderService orderService) {
4051+
this.orderService = orderService.
4052+
}
4053+
4054+
// tests that use the injected OrderService
4055+
}
4056+
----
4057+
4058+
[[testcontext-junit-jupiter-di-method]]
4059+
====== Method Injection
4060+
4061+
If a parameter in a JUnit Jupiter test method or test lifecycle callback method is of
4062+
type `ApplicationContext` (or a sub-type thereof) or is annotated or meta-annotated with
4063+
`@Autowired`, `@Qualifier`, or `@Value`, Spring will inject the value for that specific
4064+
parameter with the corresponding bean from the test's `ApplicationContext`.
4065+
4066+
In the following example, Spring will inject the `OrderService` from the
4067+
`ApplicationContext` loaded from `TestConfig.class` into the `deleteOrder()` test method.
4068+
4069+
[source,java,indent=0]
4070+
[subs="verbatim,quotes"]
4071+
----
4072+
@SpringJUnitConfig(TestConfig.class)
4073+
class OrderServiceIntegrationTests {
4074+
4075+
@Test
4076+
void deleteOrder(@Autowired OrderService orderService) {
4077+
// use orderService from the test's ApplicationContext
4078+
}
4079+
}
4080+
----
4081+
4082+
Due to the robustness of the `ParameterResolver` support in JUnit Jupiter, it is also
4083+
possible to have multiple dependencies injected into a single method not only from Spring
4084+
but also from JUnit Jupiter itself or other third-party extensions.
4085+
4086+
The following example demonstrates how to have both Spring and JUnit Jupiter inject
4087+
dependencies into the `placeOrderRepeatedly()` test method simultaneously. Note that the
4088+
use of `@RepeatedTest` from JUnit Jupiter allows the test method to gain access to the
4089+
`RepetitionInfo`.
4090+
4091+
[source,java,indent=0]
4092+
[subs="verbatim,quotes"]
4093+
----
4094+
@SpringJUnitConfig(TestConfig.class)
4095+
class OrderServiceIntegrationTests {
4096+
4097+
@RepeatedTest(10)
4098+
void placeOrderRepeatedly(
4099+
@Autowired OrderService orderService,
4100+
RepetitionInfo repetitionInfo) {
4101+
4102+
// use orderService from the test's ApplicationContext
4103+
// and repetitionInfo from JUnit Jupiter
4104+
}
4105+
}
4106+
----
4107+
4108+
39154109
[[testcontext-support-classes-testng]]
39164110
===== TestNG support classes
39174111

0 commit comments

Comments
 (0)