From 1be29d59333882495c2a20fa926b668a854dcb3d Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 9 May 2019 16:07:21 +0200 Subject: [PATCH] Document automatic constructor injection in JUnit Jupiter Closes gh-22928 --- src/docs/asciidoc/testing.adoc | 73 +++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/src/docs/asciidoc/testing.adoc b/src/docs/asciidoc/testing.adoc index 035990641f..7d226160fd 100644 --- a/src/docs/asciidoc/testing.adoc +++ b/src/docs/asciidoc/testing.adoc @@ -1189,6 +1189,7 @@ The following annotations are supported only when used in conjunction with the * <> * <> +* <> * <> * <> @@ -1281,6 +1282,35 @@ See <> as well as the javadoc for {api-spring-framework}/test/context/web/WebAppConfiguration.html[`@WebAppConfiguration`] for further details. +[[integration-testing-annotations-testconstructor]] +===== `@TestConstructor` + +`@TestConstructor` is a type-level annotation that is used to configure whether a test +class constructor should be automatically autowired from components in the test's +`ApplicationContext`. + +If `@TestConstructor` is not present or meta-present on a test class, the default _test +constructor autowire_ mode will be used. See the tip below for details on how to change +the default mode. Note, however, that a local declaration of `@Autowired` on a +constructor takes precedence over both `@TestConstructor` and the default mode. + +.Configuring the default test constructor autowire mode +[TIP] +===== +The default _test constructor autowire_ mode can be configured by setting the +`spring.test.constructor.autowire` JVM system property to `true`. Alternatively, the +default mode may be configured via the `SpringProperties` mechanism. + +If the `spring.test.constructor.autowire` property is not set, test class constructors +will not be automatically autowired. +===== + +NOTE: As of Spring Framework 5.2, `@TestConstructor` is only supported in conjunction +with the `SpringExtension` for use with JUnit Jupiter. Note that the `SpringExtension` is +often automatically registered for you – for example, when using annotations such as +`@SpringJUnitConfig` and `@SpringJUnitWebConfig` or various test-related annotations from +Spring Boot Test. + [[integration-testing-annotations-junit-jupiter-enabledif]] ===== `@EnabledIf` @@ -1386,6 +1416,7 @@ You can use each of the following as a meta-annotation in conjunction with the * `@ProfileValueSourceConfiguration` _(only supported on JUnit 4)_ * `@SpringJUnitConfig` _(only supported on JUnit Jupiter)_ * `@SpringJUnitWebConfig` _(only supported on JUnit Jupiter)_ +* `@TestConstructor` _(only supported on JUnit Jupiter)_ * `@EnabledIf` _(only supported on JUnit Jupiter)_ * `@DisabledIf` _(only supported on JUnit Jupiter)_ @@ -4423,15 +4454,25 @@ Specifically, `SpringExtension` can inject dependencies from the test's [[testcontext-junit-jupiter-di-constructor]] ====== Constructor Injection -If a parameter in a constructor for a JUnit Jupiter test class is of type +If a specific parameter in a constructor for a JUnit Jupiter test class is of type `ApplicationContext` (or a sub-type thereof) or is annotated or meta-annotated with `@Autowired`, `@Qualifier`, or `@Value`, Spring injects the value for that specific -parameter with the corresponding bean from the test's `ApplicationContext`. You can also -directly annotate a test constructor with `@Autowired` if all of the parameters should be -supplied by Spring. +parameter with the corresponding bean or value from the test's `ApplicationContext`. -WARNING: If the constructor for a test class is itself annotated with `@Autowired`, -Spring assumes the responsibility for resolving _all_ parameters in the constructor. +Spring can also be configured to autowire all arguments for a test class constructor if +the constructor is considered to be _autowirable_. A constructor is considered to be +autowirable if one of the following conditions is met (in order of precedence). + +* The constructor is annotated with `@Autowired`. +* `@TestConstructor` is present or meta-present on the test class with the `autowire` + attribute set to `true`. +* The default _test constructor autowire_ mode is set to `true`. + +See <> for details on the use of +`@TestConstructor` and how to set 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. Consequently, no other `ParameterResolver` registered with JUnit Jupiter can resolve parameters for such a constructor. @@ -4477,6 +4518,26 @@ In the following example, Spring injects the `OrderService` bean from the Note that this feature lets test dependencies be `final` and therefore immutable. +If the `spring.test.constructor.autowire` property is to `true` (see +<>), we can omit the declaration of +`@Autowired` on the constructor in the previous example resulting in the following. + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- + @SpringJUnitConfig(TestConfig.class) + class OrderServiceIntegrationTests { + + private final OrderService orderService; + + OrderServiceIntegrationTests(OrderService orderService) { + this.orderService = orderService. + } + + // tests that use the injected OrderService + } +---- + [[testcontext-junit-jupiter-di-method]] ====== Method Injection