0
# Bean Override Framework
1
2
The Bean Override Framework (since Spring Framework 6.2) provides a modern, unified approach for overriding beans in Spring tests. It offers better performance and integration compared to older mechanisms, with support for Mockito mocks/spies and custom factory methods.
3
4
## Capabilities
5
6
### MockitoBean Annotation
7
8
Creates Mockito mocks to override beans in the ApplicationContext. Can be applied to fields or at the type level for comprehensive bean overriding.
9
10
```java { .api }
11
/**
12
* Annotation that can be used to add mocks to a Spring ApplicationContext.
13
* Can be used as a field annotation or on the class level.
14
*/
15
@Target({ElementType.FIELD, ElementType.TYPE})
16
@Retention(RetentionPolicy.RUNTIME)
17
@Documented
18
@Repeatable(MockitoBeans.class)
19
@BeanOverride(MockitoBeanOverrideProcessor.class)
20
public @interface MockitoBean {
21
22
/**
23
* The name of the bean to register or replace. If not specified, the field name is used.
24
* @return the name of the bean
25
*/
26
@AliasFor("name")
27
String value() default "";
28
29
/**
30
* The name of the bean to register or replace. If not specified, the field name is used.
31
* @return the name of the bean
32
*/
33
@AliasFor("value")
34
String name() default "";
35
36
/**
37
* The classes that the mock should extend. If not specified, the field type is used.
38
* @return the classes for the mock to extend
39
*/
40
Class<?>[] types() default {};
41
42
/**
43
* The name of the application context where the mock should be added.
44
* @return the context name
45
*/
46
String contextName() default "";
47
48
/**
49
* Any extra interfaces that should be supported by the mock.
50
* @return the extra interfaces
51
*/
52
Class<?>[] extraInterfaces() default {};
53
54
/**
55
* The answers mode to use on the created mock.
56
* @return the answers mode
57
*/
58
Answers answers() default Answers.RETURNS_DEFAULTS;
59
60
/**
61
* If the generated mock is serializable.
62
* @return true if the mock is serializable
63
*/
64
boolean serializable() default false;
65
66
/**
67
* The reset mode to apply to the mock bean. The default is MockReset.AFTER meaning
68
* that mocks are automatically reset after each test method is invoked.
69
* @return the reset mode
70
*/
71
MockReset reset() default MockReset.AFTER;
72
73
/**
74
* Indicates that the annotated field requires that a bean being overridden exists.
75
* @return true if a bean override is required
76
*/
77
boolean enforceOverride() default false;
78
}
79
```
80
81
**Usage Examples:**
82
83
```java
84
@SpringBootTest
85
class UserServiceTest {
86
87
@MockitoBean
88
private UserRepository userRepository;
89
90
@MockitoBean(name = "specialService")
91
private SpecialService specialService;
92
93
@Test
94
void testUserCreation() {
95
when(userRepository.save(any(User.class)))
96
.thenReturn(new User("John", "john@example.com"));
97
98
// Test logic using mocked userRepository
99
}
100
}
101
```
102
103
### MockitoSpyBean Annotation
104
105
Creates Mockito spies to wrap existing beans in the ApplicationContext, allowing partial mocking where some methods use real implementations.
106
107
```java { .api }
108
/**
109
* Annotation that can be used to apply Mockito spies to a Spring ApplicationContext.
110
* Can be used as a field annotation or on the class level.
111
*/
112
@Target({ElementType.FIELD, ElementType.TYPE})
113
@Retention(RetentionPolicy.RUNTIME)
114
@Documented
115
@Repeatable(MockitoSpyBeans.class)
116
@BeanOverride(MockitoBeanOverrideProcessor.class)
117
public @interface MockitoSpyBean {
118
119
/**
120
* The name of the bean to spy upon. If not specified, the field name is used.
121
* @return the name of the bean
122
*/
123
@AliasFor("name")
124
String value() default "";
125
126
/**
127
* The name of the bean to spy upon. If not specified, the field name is used.
128
* @return the name of the bean
129
*/
130
@AliasFor("value")
131
String name() default "";
132
133
/**
134
* The classes that the spy should be based on. If not specified, the field type is used.
135
* @return the classes for the spy
136
*/
137
Class<?>[] types() default {};
138
139
/**
140
* The name of the application context where the spy should be applied.
141
* @return the context name
142
*/
143
String contextName() default "";
144
145
/**
146
* The reset mode to apply to the spy bean.
147
* @return the reset mode
148
*/
149
MockReset reset() default MockReset.AFTER;
150
}
151
```
152
153
**Usage Examples:**
154
155
```java
156
@SpringBootTest
157
class EmailServiceTest {
158
159
@MockitoSpyBean
160
private EmailService emailService;
161
162
@Test
163
void testEmailSending() {
164
// Spy on real EmailService, but mock specific methods
165
doNothing().when(emailService).sendEmail(anyString(), anyString());
166
167
// Other methods use real implementation
168
boolean isValid = emailService.validateEmail("test@example.com");
169
assertTrue(isValid);
170
}
171
}
172
```
173
174
### TestBean Annotation
175
176
Overrides beans using static factory methods, following convention-based discovery or explicit method naming for creating test-specific bean implementations.
177
178
```java { .api }
179
/**
180
* Annotation that can be used to override beans in a Spring ApplicationContext
181
* using a static factory method.
182
*/
183
@Target(ElementType.FIELD)
184
@Retention(RetentionPolicy.RUNTIME)
185
@Documented
186
@BeanOverride(TestBeanOverrideProcessor.class)
187
@Reflective(TestBeanReflectiveProcessor.class)
188
public @interface TestBean {
189
190
/**
191
* The name of the bean to override. If not specified, the field name is used.
192
* @return the name of the bean
193
*/
194
@AliasFor("name")
195
String value() default "";
196
197
/**
198
* The name of the bean to override. If not specified, the field name is used.
199
* @return the name of the bean
200
*/
201
@AliasFor("value")
202
String name() default "";
203
204
/**
205
* The name of the static method to use for creating the bean override.
206
* If not specified, convention-based method discovery is used.
207
* @return the method name
208
*/
209
String methodName() default "";
210
211
/**
212
* The name of the application context where the bean should be overridden.
213
* @return the context name
214
*/
215
String contextName() default "";
216
217
/**
218
* Indicates that the annotated field requires that a bean being overridden exists.
219
* @return true if a bean override is required
220
*/
221
boolean enforceOverride() default false;
222
}
223
```
224
225
**Usage Examples:**
226
227
```java
228
@SpringBootTest
229
class PaymentServiceTest {
230
231
@TestBean
232
private PaymentProcessor paymentProcessor;
233
234
@TestBean(methodName = "createCustomNotificationService")
235
private NotificationService notificationService;
236
237
@Test
238
void testPaymentProcessing() {
239
// Test using overridden beans from factory methods
240
}
241
242
// Convention-based factory method (matches field name)
243
static PaymentProcessor paymentProcessor() {
244
return new MockPaymentProcessor();
245
}
246
247
// Explicit factory method
248
static NotificationService createCustomNotificationService() {
249
return new TestNotificationService();
250
}
251
}
252
```
253
254
### MockReset Enum
255
256
Controls when Mockito mocks and spies are reset during test execution.
257
258
```java { .api }
259
/**
260
* Reset mode to apply to a mock bean. Usually applied to a mock that is shared across several test methods.
261
*/
262
public enum MockReset {
263
264
/**
265
* Reset the mock before the test method runs. This option ensures the mock is reset
266
* before each test method, which is useful when you need a clean mock state.
267
*/
268
BEFORE,
269
270
/**
271
* Reset the mock after the test method runs. This is the default option and
272
* ensures that mock interactions don't leak between test methods.
273
*/
274
AFTER,
275
276
/**
277
* Do not reset the mock. Use this option when you want to preserve mock state
278
* across multiple test methods or when manually managing mock resets.
279
*/
280
NONE;
281
282
/**
283
* Create MockSettings with BEFORE reset mode.
284
* @return MockSettings configured for reset before test methods
285
*/
286
public static MockSettings before();
287
288
/**
289
* Create MockSettings with AFTER reset mode.
290
* @return MockSettings configured for reset after test methods
291
*/
292
public static MockSettings after();
293
294
/**
295
* Create MockSettings with the specified reset mode.
296
* @param reset the reset mode to apply
297
* @return MockSettings with the specified reset configuration
298
*/
299
public static MockSettings withSettings(MockReset reset);
300
301
/**
302
* Apply the reset mode to existing MockSettings.
303
* @param reset the reset mode to apply
304
* @param settings existing MockSettings to modify
305
* @return modified MockSettings with reset configuration
306
*/
307
public static MockSettings apply(MockReset reset, MockSettings settings);
308
}
309
```
310
311
### Container Annotations
312
313
Container annotations for repeatable @MockitoBean and @MockitoSpyBean usage.
314
315
```java { .api }
316
/**
317
* Container annotation that aggregates several @MockitoBean annotations.
318
*/
319
@Target(ElementType.TYPE)
320
@Retention(RetentionPolicy.RUNTIME)
321
@Documented
322
public @interface MockitoBeans {
323
/**
324
* @return the contained @MockitoBean annotations
325
*/
326
MockitoBean[] value();
327
}
328
329
/**
330
* Container annotation that aggregates several @MockitoSpyBean annotations.
331
*/
332
@Target(ElementType.TYPE)
333
@Retention(RetentionPolicy.RUNTIME)
334
@Documented
335
public @interface MockitoSpyBeans {
336
/**
337
* @return the contained @MockitoSpyBean annotations
338
*/
339
MockitoSpyBean[] value();
340
}
341
```
342
343
### BeanOverrideTestExecutionListener
344
345
TestExecutionListener that enables Bean Override support by processing annotations and injecting overridden beans.
346
347
```java { .api }
348
/**
349
* TestExecutionListener which provides support for Bean Override annotations.
350
*/
351
public class BeanOverrideTestExecutionListener extends AbstractTestExecutionListener {
352
353
/**
354
* The order of this listener - runs early to set up bean overrides.
355
*/
356
public static final int ORDER = 1950;
357
358
/**
359
* Get the order of this listener.
360
* @return the order value
361
*/
362
@Override
363
public int getOrder();
364
365
/**
366
* Prepare the test instance by injecting bean override fields.
367
* @param testContext the test context
368
* @throws Exception if preparation fails
369
*/
370
@Override
371
public void prepareTestInstance(TestContext testContext) throws Exception;
372
373
/**
374
* Prepare for test method execution by resetting mocks if configured.
375
* @param testContext the test context
376
* @throws Exception if preparation fails
377
*/
378
@Override
379
public void beforeTestMethod(TestContext testContext) throws Exception;
380
}
381
```
382
383
### Types
384
385
```java { .api }
386
/**
387
* Strategy for how a bean override should be processed.
388
*/
389
public enum BeanOverrideStrategy {
390
/**
391
* Replace a given bean, immediately preparing a singleton instance.
392
* Fails if the original bean does not exist.
393
*/
394
REPLACE,
395
396
/**
397
* Replace or create a given bean, immediately preparing a singleton instance.
398
* Creates a new bean if the target bean does not exist.
399
*/
400
REPLACE_OR_CREATE,
401
402
/**
403
* Intercept and process an early bean reference, allowing variants of bean
404
* overriding to wrap the original bean instance.
405
*/
406
WRAP
407
}
408
409
/**
410
* Meta-annotation for creating custom bean override annotations.
411
*/
412
@Retention(RetentionPolicy.RUNTIME)
413
@Target(ElementType.ANNOTATION_TYPE)
414
@Documented
415
@Reflective(BeanOverrideReflectiveProcessor.class)
416
public @interface BeanOverride {
417
/**
418
* The BeanOverrideProcessor implementation to use.
419
* @return the processor class
420
*/
421
Class<? extends BeanOverrideProcessor> value();
422
}
423
```