11[[spring-testing-annotation-beanoverriding-mockitobean]]
22= `@MockitoBean` and `@MockitoSpyBean`
33
4- `@MockitoBean` and `@MockitoSpyBean` are used on non-static fields in test classes to
5- override beans in the test's `ApplicationContext` with a Mockito _mock_ or _spy_,
6- respectively. In the latter case, an early instance of the original bean is captured and
7- wrapped by the spy.
4+ `@MockitoBean` and `@MockitoSpyBean` can be used in test classes to override a bean in
5+ the test's `ApplicationContext` with a Mockito _mock_ or _spy_, respectively. In the
6+ latter case, an early instance of the original bean is captured and wrapped by the spy.
7+
8+ The annotations can be applied in the following ways.
9+
10+ * On a non-static field in a test class or any of its superclasses.
11+ * On a non-static field in an enclosing class for a `@Nested` test class or in any class
12+ in the type hierarchy or enclosing class hierarchy above the `@Nested` test class.
13+ * At the type level on a test class or any superclass or implemented interface in the
14+ type hierarchy above the test class.
15+ * At the type level on an enclosing class for a `@Nested` test class or on any class or
16+ interface in the type hierarchy or enclosing class hierarchy above the `@Nested` test
17+ class.
18+
19+ When `@MockitoBean` or `@MockitoSpyBean` is declared on a field, the bean to mock or spy
20+ is inferred from the type of the annotated field. If multiple candidates exist in the
21+ `ApplicationContext`, a `@Qualifier` annotation can be declared on the field to help
22+ disambiguate. In the absence of a `@Qualifier` annotation, the name of the annotated
23+ field will be used as a _fallback qualifier_. Alternatively, you can explicitly specify a
24+ bean name to mock or spy by setting the `value` or `name` attribute in the annotation.
25+
26+ When `@MockitoBean` or `@MockitoSpyBean` is declared at the type level, the type of bean
27+ (or beans) to mock or spy must be supplied via the `types` attribute in the annotation –
28+ for example, `@MockitoBean(types = {OrderService.class, UserService.class})`. If multiple
29+ candidates exist in the `ApplicationContext`, you can explicitly specify a bean name to
30+ mock or spy by setting the `name` attribute. Note, however, that the `types` attribute
31+ must contain a single type if an explicit bean `name` is configured – for example,
32+ `@MockitoBean(name = "ps1", types = PrintingService.class)`.
833
9- By default, the annotated field's type is used to search for candidate beans to override.
10- If multiple candidates match, `@Qualifier` can be provided to narrow the candidate to
11- override. Alternatively, a candidate whose bean name matches the name of the field will
12- match.
34+ To support reuse of mock configuration, `@MockitoBean` and `@MockitoSpyBean` may be used
35+ as meta-annotations to create custom _composed annotations_ – for example, to define
36+ common mock or spy configuration in a single annotation that can be reused across a test
37+ suite. `@MockitoBean` and `@MockitoSpyBean` can also be used as repeatable annotations at
38+ the type level — for example, to mock or spy several beans by name.
1339
1440[WARNING]
1541====
16- Qualifiers, including the name of the field, are used to determine if a separate
42+ Qualifiers, including the name of a field, are used to determine if a separate
1743`ApplicationContext` needs to be created. If you are using this feature to mock or spy
18- the same bean in several test classes, make sure to name the field consistently to avoid
44+ the same bean in several test classes, make sure to name the fields consistently to avoid
1945creating unnecessary contexts.
2046====
2147
2248Each annotation also defines Mockito-specific attributes to fine-tune the mocking behavior.
2349
2450The `@MockitoBean` annotation uses the `REPLACE_OR_CREATE`
25- xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-custom [strategy for test bean overriding ].
26- If no existing bean matches , a new bean is created on the fly . However, you can switch to
27- the `REPLACE` strategy by setting the `enforceOverride` attribute to `true`. See the
28- following section for an example .
51+ xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-strategy [strategy for bean overrides ].
52+ If a corresponding bean does not exist , a new bean will be created . However, you can
53+ switch to the `REPLACE` strategy by setting the `enforceOverride` attribute to `true` –
54+ for example, `@MockitoBean(enforceOverride = true)` .
2955
3056The `@MockitoSpyBean` annotation uses the `WRAP`
31- xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-custom [strategy],
57+ xref:testing/testcontext-framework/bean-overriding.adoc#testcontext-bean-overriding-strategy [strategy],
3258and the original instance is wrapped in a Mockito spy. This strategy requires that
3359exactly one candidate bean exists.
3460
@@ -56,15 +82,8 @@ or `private` depending on the needs or coding practices of the project.
5682[[spring-testing-annotation-beanoverriding-mockitobean-examples]]
5783== `@MockitoBean` Examples
5884
59- When using `@MockitoBean`, a new bean will be created if a corresponding bean does not
60- exist. However, if you would like for the test to fail when a corresponding bean does not
61- exist, you can set the `enforceOverride` attribute to `true` – for example,
62- `@MockitoBean(enforceOverride = true)`.
63-
64- To use a by-name override rather than a by-type override, specify the `name` (or `value`)
65- attribute of the annotation.
66-
67- The following example shows how to use the default behavior of the `@MockitoBean` annotation:
85+ The following example shows how to use the default behavior of the `@MockitoBean`
86+ annotation.
6887
6988[tabs]
7089======
@@ -81,7 +100,7 @@ Java::
81100 // tests...
82101 }
83102----
84- <1> Replace the bean with type `CustomService` with a Mockito ` mock` .
103+ <1> Replace the bean with type `CustomService` with a Mockito mock.
85104======
86105
87106In the example above, we are creating a mock for `CustomService`. If more than one bean
@@ -90,7 +109,8 @@ will fail, and you will need to provide a qualifier of some sort to identify whi
90109`CustomService` beans you want to override. If no such bean exists, a bean will be
91110created with an auto-generated bean name.
92111
93- The following example uses a by-name lookup, rather than a by-type lookup:
112+ The following example uses a by-name lookup, rather than a by-type lookup. If no bean
113+ named `service` exists, one is created.
94114
95115[tabs]
96116======
@@ -108,32 +128,9 @@ Java::
108128
109129 }
110130----
111- <1> Replace the bean named `service` with a Mockito ` mock` .
131+ <1> Replace the bean named `service` with a Mockito mock.
112132======
113133
114- If no bean named `service` exists, one is created.
115-
116- `@MockitoBean` can also be used at the type level:
117-
118- - on a test class or any superclass or implemented interface in the type hierarchy above
119- the test class
120- - on an enclosing class for a `@Nested` test class or on any class or interface in the
121- type hierarchy or enclosing class hierarchy above the `@Nested` test class
122-
123- When `@MockitoBean` is declared at the type level, the type of bean (or beans) to mock
124- must be supplied via the `types` attribute – for example,
125- `@MockitoBean(types = {OrderService.class, UserService.class})`. If multiple candidates
126- exist in the application context, you can explicitly specify a bean name to mock by
127- setting the `name` attribute. Note, however, that the `types` attribute must contain a
128- single type if an explicit bean `name` is configured – for example,
129- `@MockitoBean(name = "ps1", types = PrintingService.class)`.
130-
131- To support reuse of mock configuration, `@MockitoBean` may be used as a meta-annotation
132- to create custom _composed annotations_ — for example, to define common mock
133- configuration in a single annotation that can be reused across a test suite.
134- `@MockitoBean` can also be used as a repeatable annotation at the type level — for
135- example, to mock several beans by name.
136-
137134The following `@SharedMocks` annotation registers two mocks by-type and one mock by-name.
138135
139136[tabs]
@@ -191,7 +188,7 @@ APIs.
191188== `@MockitoSpyBean` Examples
192189
193190The following example shows how to use the default behavior of the `@MockitoSpyBean`
194- annotation:
191+ annotation.
195192
196193[tabs]
197194======
@@ -208,15 +205,15 @@ Java::
208205 // tests...
209206 }
210207----
211- <1> Wrap the bean with type `CustomService` with a Mockito ` spy` .
208+ <1> Wrap the bean with type `CustomService` with a Mockito spy.
212209======
213210
214211In the example above, we are wrapping the bean with type `CustomService`. If more than
215212one bean of that type exists, the bean named `customService` is considered. Otherwise,
216213the test will fail, and you will need to provide a qualifier of some sort to identify
217214which of the `CustomService` beans you want to spy.
218215
219- The following example uses a by-name lookup, rather than a by-type lookup:
216+ The following example uses a by-name lookup, rather than a by-type lookup.
220217
221218[tabs]
222219======
@@ -233,5 +230,58 @@ Java::
233230 // tests...
234231 }
235232----
236- <1> Wrap the bean named `service` with a Mockito `spy`.
233+ <1> Wrap the bean named `service` with a Mockito spy.
234+ ======
235+
236+ The following `@SharedSpies` annotation registers two spies by-type and one spy by-name.
237+
238+ [tabs]
239+ ======
240+ Java::
241+ +
242+ [source,java,indent=0,subs="verbatim,quotes"]
243+ ----
244+ @Target(ElementType.TYPE)
245+ @Retention(RetentionPolicy.RUNTIME)
246+ @MockitoSpyBean(types = {OrderService.class, UserService.class}) // <1>
247+ @MockitoSpyBean(name = "ps1", types = PrintingService.class) // <2>
248+ public @interface SharedSpies {
249+ }
250+ ----
251+ <1> Register `OrderService` and `UserService` spies by-type.
252+ <2> Register `PrintingService` spy by-name.
253+ ======
254+
255+ The following demonstrates how `@SharedSpies` can be used on a test class.
256+
257+ [tabs]
258+ ======
259+ Java::
260+ +
261+ [source,java,indent=0,subs="verbatim,quotes"]
262+ ----
263+ @SpringJUnitConfig(TestConfig.class)
264+ @SharedSpies // <1>
265+ class BeanOverrideTests {
266+
267+ @Autowired OrderService orderService; // <2>
268+
269+ @Autowired UserService userService; // <2>
270+
271+ @Autowired PrintingService ps1; // <2>
272+
273+ // Inject other components that rely on the spies.
274+
275+ @Test
276+ void testThatDependsOnMocks() {
277+ // ...
278+ }
279+ }
280+ ----
281+ <1> Register common spies via the custom `@SharedSpies` annotation.
282+ <2> Optionally inject spies to _stub_ or _verify_ them.
237283======
284+
285+ TIP: The spies can also be injected into `@Configuration` classes or other test-related
286+ components in the `ApplicationContext` in order to configure them with Mockito's stubbing
287+ APIs.
0 commit comments