Use by-type semantics in bean overriding if no explicit name is provided

This change switches default behavior of `@TestBean`, `@MockitoBean` and
`@MockitoSpyBean` to match the bean definition / bean to override by
type in the case there is no explicit bean name provided via the
annotation. The previous behavior of using the annotated field's name
is still an option for implementors, but no longer the default.

Closes gh-32761
This commit is contained in:
Simon Baslé
2024-05-14 12:35:22 +02:00
parent fc07946e60
commit a86612a254
19 changed files with 483 additions and 73 deletions

View File

@@ -6,17 +6,24 @@ 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.
By default, the name of the bean to override is derived from the annotated field's name,
but both annotations allow for a specific `name` to be provided. Each annotation also
defines Mockito-specific attributes to fine-tune the mocking details.
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.
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.
The `@MockitoSpyBean` annotation uses the `WRAP_BEAN`
xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-custom[strategy],
and the original instance is wrapped in a Mockito spy.
It requires that exactly one candidate definition exists.
The following example shows how to configure the bean name via `@MockitoBean` and
`@MockitoSpyBean`:

View File

@@ -5,12 +5,17 @@
`ApplicationContext` with an instance provided by a conventionally named static factory
method.
By default, the bean name and the associated factory method name are derived from the
annotated field's name, but the annotation allows for specific values to be provided.
By default, the associated factory method name is derived from the annotated field's name,
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.
The following example shows how to fully configure the `@TestBean` annotation, with
explicit values equivalent to the defaults:

View File

@@ -58,10 +58,14 @@ by the corresponding `BeanOverrideStrategy`:
[NOTE]
====
In contrast to Spring's autowiring mechanism (for example, resolution of an `@Autowired`
field), the bean overriding infrastructure in the TestContext framework does not perform
any heuristics to locate a bean. Instead, the name of the bean to override must be
explicitly provided to or computed by the `BeanOverrideProcessor`.
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.
Typically, the user provides the bean name via a custom annotation, or the
`BeanOverrideProcessor` determines the bean name based on some convention.
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.
====