1
1
[[spring-testing-annotation-beanoverriding-mockitobean]]
2
2
= `@MockitoBean` and `@MockitoSpyBean`
3
3
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)`.
8
33
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.
13
39
14
40
[WARNING]
15
41
====
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
17
43
`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
19
45
creating unnecessary contexts.
20
46
====
21
47
22
48
Each annotation also defines Mockito-specific attributes to fine-tune the mocking behavior.
23
49
24
50
The `@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)` .
29
55
30
56
The `@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],
32
58
and the original instance is wrapped in a Mockito spy. This strategy requires that
33
59
exactly one candidate bean exists.
34
60
@@ -56,15 +82,8 @@ or `private` depending on the needs or coding practices of the project.
56
82
[[spring-testing-annotation-beanoverriding-mockitobean-examples]]
57
83
== `@MockitoBean` Examples
58
84
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.
68
87
69
88
[tabs]
70
89
======
@@ -81,7 +100,7 @@ Java::
81
100
// tests...
82
101
}
83
102
----
84
- <1> Replace the bean with type `CustomService` with a Mockito ` mock` .
103
+ <1> Replace the bean with type `CustomService` with a Mockito mock.
85
104
======
86
105
87
106
In 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
90
109
`CustomService` beans you want to override. If no such bean exists, a bean will be
91
110
created with an auto-generated bean name.
92
111
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.
94
114
95
115
[tabs]
96
116
======
@@ -108,32 +128,9 @@ Java::
108
128
109
129
}
110
130
----
111
- <1> Replace the bean named `service` with a Mockito ` mock` .
131
+ <1> Replace the bean named `service` with a Mockito mock.
112
132
======
113
133
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
-
137
134
The following `@SharedMocks` annotation registers two mocks by-type and one mock by-name.
138
135
139
136
[tabs]
@@ -191,7 +188,7 @@ APIs.
191
188
== `@MockitoSpyBean` Examples
192
189
193
190
The following example shows how to use the default behavior of the `@MockitoSpyBean`
194
- annotation:
191
+ annotation.
195
192
196
193
[tabs]
197
194
======
@@ -208,15 +205,15 @@ Java::
208
205
// tests...
209
206
}
210
207
----
211
- <1> Wrap the bean with type `CustomService` with a Mockito ` spy` .
208
+ <1> Wrap the bean with type `CustomService` with a Mockito spy.
212
209
======
213
210
214
211
In the example above, we are wrapping the bean with type `CustomService`. If more than
215
212
one bean of that type exists, the bean named `customService` is considered. Otherwise,
216
213
the test will fail, and you will need to provide a qualifier of some sort to identify
217
214
which of the `CustomService` beans you want to spy.
218
215
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.
220
217
221
218
[tabs]
222
219
======
@@ -233,5 +230,58 @@ Java::
233
230
// tests...
234
231
}
235
232
----
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.
237
283
======
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