As of Spring Framework 6.2.13, we support JUnit Jupiter 5.12's
ExtensionContextScope.TEST_METHOD behavior in the SpringExtension and
the BeanOverrideTestExecutionListener; however, users can only benefit
from that if they explicitly set the following configuration parameter
for their entire test suite, which may have adverse effects on other
third-party JUnit Jupiter extensions.
junit.jupiter.extensions.testinstantiation.extensioncontextscope.default=test_method
For Spring Framework 7.0, in order to support dependency injection into
test class constructors and fields in @Nested test class hierarchies
from the same ApplicationContext that is already used to perform
dependency injection into lifecycle and test methods (@BeforeEach,
@AfterEach, @Test, etc.), we have decided to configure the
SpringExtension to use ExtensionContextScope.TEST_METHOD by default. In
addition, we have decided to provide a mechanism for users to switch
back to the legacy "test-class scoped ExtensionContext" behavior in
case third-party TestExecutionListener implementations are not yet
compatible with test-method scoped ExtensionContext and TestContext
semantics.
This commit achieves the above goals as follows.
- A new @SpringExtensionConfig annotation has been introduced, which
allows developers to configure the effective ExtensionContext scope
used by the SpringExtension.
- The SpringExtension now overrides
getTestInstantiationExtensionContextScope() to return
ExtensionContextScope.TEST_METHOD.
- The postProcessTestInstance() and resolveParameter() methods in the
SpringExtension now find the properly scoped ExtensionContext for the
supplied test class, based on whether the @Nested test class
hierarchy is annotated with
@SpringExtensionConfig(useTestClassScopedExtensionContext = true).
See gh-35680
See gh-35716
Closes gh-35697
Although gh-35680 introduced support for JUnit Jupiter's TEST_METHOD
ExtensionContextScope in the SpringExtension and
BeanOverrideTestExecutionListener, those were internal changes that are
not directly visible by TestExecutionListener authors.
However, in order to be compatible with a test-method scoped
TestContext (which takes its values from the current Jupiter
ExtensionContext), existing third-party TestExecutionListener
implementations may need to be modified similar to how
BeanOverrideTestExecutionListener was modified in commit d24a31d469.
To raise awareness of how to deal with such issues, this commit
documents test-method TestContext semantics for TestExecutionListener
authors.
Closes gh-35716
Since we now officially support the TEST_METHOD ExtensionContextScope
(see gh-35676 and gh-35680), this commit introduces tests which
demonstrate that the issue raised in gh-34576 is no longer an "issue" if
the user indirectly configures the SpringExtension to use the TEST_METHOD
scope via the "junit.jupiter.extensions.testinstantiation.extensioncontextscope.default"
configuration parameter.
Historically, @Autowired fields in an enclosing class of a @Nested
test class have been injected from the ApplicationContext for the
enclosing class. If the enclosing test class and @Nested test class
share the same ApplicationContext configuration, things work as
developers expect. However, if the enclosing class and @Nested test
class have different ApplicationContexts, that can lead to
difficult-to-debug scenarios. For example, a bean injected into the
enclosing test class will not participate in a test-managed transaction
in the @Nested test class (see gh-34576).
JUnit Jupiter 5.12 introduced a new ExtensionContextScope feature which
allows the SpringExtension to behave the same for @Autowired fields as
it already does for @Autowired arguments in lifecycle and test
methods. Specifically, if a developer sets the ExtensionContextScope to
TEST_METHOD — for example, by configuring the following configuration
parameter as a JVM system property or in a `junit-platform.properties`
file — the SpringExtension already supports dependency injection from
the current, @Nested ApplicationContext in @Autowired fields in an
enclosing class of the @Nested test class.
junit.jupiter.extensions.testinstantiation.extensioncontextscope.default=test_method
However, there are two scenarios that fail as of Spring Framework
6.2.12.
1. @TestConstructor configuration in @Nested class hierarchies.
2. Field injection for bean overrides (such as @MockitoBean) in
@Nested class hierarchies.
Commit 82c34f7b51 fixed the SpringExtension to support scenario #2
above.
To fix scenario #1, this commit revises
BeanOverrideTestExecutionListener's injectField() implementation to
look up the fields to inject for the "current test instance" instead of
for the "current test class".
This commit also introduces tests for both scenarios.
See gh-34576
See gh-35676
Closes gh-35680
This commit introduces a new isAutowirableConstructor(Executable, PropertyProvider)
overload in TestConstructorUtils and deprecates all other existing variants
for removal in 7.1.
Closes gh-35676
This commit removes JSpecify (TYPE_USE) annotations on
org.hamcrest.Matcher parameters to prevent a related
"Cannot attach type annotations" error when Hamcrest
(optional dependency) is not in the classpath with Java > 22.
Closes gh-35666
Compose consumers and apply them together from the build method
to allow multiple parties to supply consumers that collaborate
on the same HttpMessageConverters.Builder.
See gh-35578
Prior to this commit, the BeanOverrideBeanFactoryPostProcessor rejected
any attempt to override a non-singleton bean; however, due to interest
from the community, we have decided to provide support for overriding
non-singleton beans via the Bean Override mechanism — for example, when
using @MockitoBean, @MockitoSpyBean, and @TestBean.
With this commit, we now support Bean Overrides for non-singletons: for
standard JVM runtimes as well as AOT processing and AOT runtimes. This
commit also documents that non-singletons will effectively be converted
to singletons when overridden and logs a warning similar to the
following.
WARN: BeanOverrideBeanFactoryPostProcessor - Converting 'prototype' scoped bean definition 'myBean' to a singleton.
See gh-33602
See gh-32933
See gh-33800
Closes gh-35574
At some point, TestNG started implementing listener methods as interface
default methods, so we no longer need to override those methods with
empty implementations.
Prior to this commit, AbstractTestNGSpringContextTests was not
thread-safe with regard to tracked exceptions.
To address that, AbstractTestNGSpringContextTests now tracks the test
exception via a ThreadLocal.
Closes gh-35528