Bean overriding by type uses isAutowireCandidate for matching

This commit uses the bean factory `isAutowiredCandidate` method directly
in `BeanOverrideBeanFactoryPostProcessor` to select a single match among
multiple candidates when matching by type.

The expected consequence, in most cases, is that this will delegate to
a `@Qualifier`-aware `QualifierAnnotationAutowireCandidateResolver`.
In that sense, bean overriding by-type matching is now potentially
taking Qualifier annotations or meta-annotations into account.

It also changes the way existing bean definitions are checked in case
a bean name has been specified: factory beans are now taken into account
when checking the type of an existing definition matches the expected
bean override type.

Closes gh-32822
This commit is contained in:
Simon Baslé
2024-05-17 16:57:57 +02:00
parent b17d1c5124
commit d5c7a5e2db
12 changed files with 319 additions and 43 deletions

View File

@@ -6,17 +6,18 @@ the test's `ApplicationContext` with a Mockito mock or spy, respectively. In the
case, the original bean definition is not replaced, but instead an early instance of the
bean is captured and wrapped by the spy.
Users are encouraged to make bean overriding as explicit and unambiguous as possible,
typically by specifying a bean `name` in the annotation.
If no bean `name` is specified, the annotated field's type is used to search for candidate
definitions to override.
By default, the annotated field's type is used to search for candidate definitions to
override, but note that `@Qualifier` annotations are also taken into account for the
purpose of matching. Users can also make things entirely explicit by specifying a bean
`name` in the annotation.
Each annotation also defines Mockito-specific attributes to fine-tune the mocking details.
The `@MockitoBean` annotation uses the `REPLACE_OR_CREATE_DEFINITION`
xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-custom[strategy for test bean overriding].
It requires that at most one candidate definition exists if a bean name is specified,
or exactly one if no bean name is specified.
It requires that at most one matching candidate definition exists if a bean name
is specified, or exactly one if no bean name is specified.
The `@MockitoSpyBean` annotation uses the `WRAP_BEAN`
xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-custom[strategy],

View File

@@ -11,10 +11,10 @@ but the annotation allows for a specific method name to be provided.
The `@TestBean` annotation uses the `REPLACE_DEFINITION`
xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-custom[strategy for test bean overriding].
Users are encouraged to make bean overriding as explicit and unambiguous as possible,
typically by specifying a bean `name` in the annotation.
If no bean `name` is specified, the annotated field's type is used to search for candidate
definitions to override. In that case it is required that exactly one definition matches.
By default, the annotated field's type is used to search for candidate definitions to override.
In that case it is required that exactly one definition matches, but note that `@Qualifier`
annotations are also taken into account for the purpose of matching.
Users can also make things entirely explicit by specifying a bean `name` in the annotation.
The following example shows how to fully configure the `@TestBean` annotation, with
explicit values equivalent to the defaults:

View File

@@ -61,11 +61,11 @@ In contrast to Spring's autowiring mechanism (for example, resolution of an `@Au
field), the bean overriding infrastructure in the TestContext framework has limited
heuristics it can perform to locate a bean. Either the `BeanOverrideProcessor` can compute
the name of the bean to override, or it can be unambiguously selected given the type of
the annotated field.
the annotated field and its qualifying annotations.
Typically, the bean is selected by type by the `BeanOverrideFactoryPostProcessor`.
Alternatively, the user can directly provide the bean name in the custom annotation.
Typically, the user directly provides the bean name in the custom annotation in order to
make things as explicit as possible. Alternatively, the bean is selected by type by the
`BeanOverrideFactoryPostProcessor`.
Some `BeanOverrideProcessor`s could also internally compute a bean name based on a
convention or another advanced method.
====