0
# JUnit Integration
1
2
Mockito provides seamless integration with JUnit testing framework through runners and rules, enabling automatic mock initialization and enhanced debugging capabilities.
3
4
## JUnit Runners
5
6
### MockitoJUnitRunner
7
8
Automatically initializes mocks without requiring explicit setup:
9
10
```java { .api }
11
public class MockitoJUnitRunner extends Runner { }
12
```
13
14
**Usage:**
15
16
```java
17
import org.junit.runner.RunWith;
18
import org.mockito.runners.MockitoJUnitRunner;
19
20
@RunWith(MockitoJUnitRunner.class)
21
public class UserServiceTest {
22
23
@Mock
24
private UserRepository userRepository;
25
26
@Mock
27
private EmailService emailService;
28
29
@InjectMocks
30
private UserService userService;
31
32
// No need for MockitoAnnotations.initMocks(this)
33
34
@Test
35
public void testUserCreation() {
36
when(userRepository.save(any(User.class))).thenReturn(user);
37
38
User result = userService.createUser("John", "john@example.com");
39
40
verify(emailService).sendWelcomeEmail(user);
41
assertEquals("John", result.getName());
42
}
43
}
44
```
45
46
### VerboseMockitoJUnitRunner
47
48
Enhanced debugging with detailed output:
49
50
```java { .api }
51
public class VerboseMockitoJUnitRunner extends MockitoJUnitRunner { }
52
```
53
54
**Usage:**
55
56
```java
57
@RunWith(VerboseMockitoJUnitRunner.class)
58
public class UserServiceTest {
59
@Mock private UserRepository userRepository;
60
@InjectMocks private UserService userService;
61
62
@Test
63
public void testWithVerboseOutput() {
64
// Test implementation
65
// Runner will provide detailed output for debugging
66
}
67
}
68
```
69
70
**Benefits of Verbose Runner:**
71
- Detailed mock interaction logging
72
- Enhanced error messages with stack traces
73
- Better debugging information for test failures
74
- Helps identify unused stubs and interactions
75
76
### ConsoleSpammingMockitoJUnitRunner
77
78
Prints warnings and hints to console:
79
80
```java { .api }
81
public class ConsoleSpammingMockitoJUnitRunner extends MockitoJUnitRunner { }
82
```
83
84
**Usage:**
85
86
```java
87
@RunWith(ConsoleSpammingMockitoJUnitRunner.class)
88
public class UserServiceTest {
89
// Prints warnings about unused stubs, potential issues, etc.
90
}
91
```
92
93
## JUnit Rules
94
95
### MockitoRule
96
97
Alternative to runners when you can't use `@RunWith`:
98
99
```java { .api }
100
public interface MockitoRule extends TestRule { }
101
102
public class MockitoJUnit {
103
public static MockitoRule rule();
104
}
105
```
106
107
**Basic Usage:**
108
109
```java
110
import org.junit.Rule;
111
import org.mockito.junit.MockitoJUnit;
112
import org.mockito.junit.MockitoRule;
113
114
public class UserServiceTest {
115
116
@Rule
117
public MockitoRule mockitoRule = MockitoJUnit.rule();
118
119
@Mock
120
private UserRepository userRepository;
121
122
@InjectMocks
123
private UserService userService;
124
125
@Test
126
public void testUserService() {
127
// Mocks are automatically initialized
128
when(userRepository.findById(1)).thenReturn(user);
129
130
User result = userService.getUser(1);
131
132
assertEquals(user, result);
133
}
134
}
135
```
136
137
### Rule with Custom Configuration
138
139
```java
140
public class UserServiceTest {
141
142
@Rule
143
public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
144
145
// Strict mode helps catch unused stubs and other issues
146
}
147
```
148
149
## Integration Patterns
150
151
### Combining with Other Runners
152
153
When you need multiple runners, use rules instead:
154
155
```java
156
@RunWith(SpringJUnit4ClassRunner.class)
157
@ContextConfiguration(classes = TestConfig.class)
158
public class IntegrationTest {
159
160
@Rule
161
public MockitoRule mockitoRule = MockitoJUnit.rule();
162
163
@Autowired
164
private ApplicationService applicationService;
165
166
@Mock
167
private ExternalService externalService;
168
169
@Test
170
public void testIntegration() {
171
// Mix Spring integration with Mockito mocks
172
}
173
}
174
```
175
176
### JUnit 5 Integration
177
178
For JUnit 5, use the MockitoExtension:
179
180
```java
181
import org.junit.jupiter.api.extension.ExtendWith;
182
import org.mockito.junit.jupiter.MockitoExtension;
183
184
@ExtendWith(MockitoExtension.class)
185
class UserServiceTest {
186
187
@Mock
188
private UserRepository userRepository;
189
190
@InjectMocks
191
private UserService userService;
192
193
@Test
194
void testUserCreation() {
195
// Test implementation
196
}
197
}
198
```
199
200
## Test Lifecycle Integration
201
202
### Manual Initialization
203
204
When you can't use runners or rules:
205
206
```java
207
public class UserServiceTest {
208
209
@Mock private UserRepository userRepository;
210
@InjectMocks private UserService userService;
211
212
@Before
213
public void setUp() {
214
MockitoAnnotations.initMocks(this);
215
}
216
217
@After
218
public void tearDown() {
219
// Optional cleanup
220
validateMockitoUsage();
221
}
222
223
@Test
224
public void testUser() {
225
// Test implementation
226
}
227
}
228
```
229
230
### Base Test Class Pattern
231
232
```java
233
public abstract class BaseMockitoTest {
234
235
@Before
236
public void setUpMocks() {
237
MockitoAnnotations.initMocks(this);
238
}
239
240
@After
241
public void validateMocks() {
242
validateMockitoUsage();
243
}
244
}
245
246
public class UserServiceTest extends BaseMockitoTest {
247
248
@Mock private UserRepository userRepository;
249
@InjectMocks private UserService userService;
250
251
@Test
252
public void testUser() {
253
// Test implementation inherits mock setup
254
}
255
}
256
```
257
258
## Debugging and Troubleshooting
259
260
### Validation
261
262
Enable automatic validation of Mockito usage:
263
264
```java
265
@After
266
public void validateMockitoUsage() {
267
Mockito.validateMockitoUsage();
268
}
269
```
270
271
**What it catches:**
272
- Unfinished stubbing
273
- Unused stubs
274
- Unnecessary stubs
275
- Invalid use of matchers
276
277
### Verbose Output Example
278
279
```java
280
@RunWith(VerboseMockitoJUnitRunner.class)
281
public class DebuggingTest {
282
283
@Mock private Service service;
284
285
@Test
286
public void testWithDebugging() {
287
when(service.process("input")).thenReturn("output");
288
when(service.process("unused")).thenReturn("never_used"); // Unused stub
289
290
String result = service.process("input");
291
292
// VerboseMockitoJUnitRunner will report:
293
// - Used stubs
294
// - Unused stubs (potential issues)
295
// - All interactions
296
}
297
}
298
```
299
300
### Console Output Configuration
301
302
```java
303
@RunWith(ConsoleSpammingMockitoJUnitRunner.class)
304
public class ConsoleOutputTest {
305
306
@Mock private Service service;
307
308
@Test
309
public void testWithConsoleOutput() {
310
// Console will show:
311
// [MockitoHint] You have unused stubbings in this test...
312
// [MockitoHint] Consider removing unnecessary stubbings...
313
}
314
}
315
```
316
317
## Best Practices
318
319
### Choose the Right Integration Method
320
321
```java
322
// Use MockitoJUnitRunner for simple cases
323
@RunWith(MockitoJUnitRunner.class)
324
public class SimpleTest { }
325
326
// Use MockitoRule when combining with other runners
327
@RunWith(SpringRunner.class)
328
public class SpringIntegrationTest {
329
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
330
}
331
332
// Use manual initialization for maximum control
333
public class ComplexTest {
334
@Before public void setUp() { MockitoAnnotations.initMocks(this); }
335
}
336
```
337
338
### Test Organization
339
340
```java
341
@RunWith(MockitoJUnitRunner.class)
342
public class UserServiceTest {
343
344
// Group related mocks
345
@Mock private UserRepository userRepository;
346
@Mock private UserValidator userValidator;
347
@Mock private UserNotificationService notificationService;
348
349
// Service under test
350
@InjectMocks private UserService userService;
351
352
// Test data setup
353
private User testUser;
354
355
@Before
356
public void setUp() {
357
testUser = new User("John", "john@example.com");
358
}
359
360
@Test
361
public void shouldCreateValidUser() {
362
// Given
363
when(userValidator.isValid(testUser)).thenReturn(true);
364
when(userRepository.save(testUser)).thenReturn(testUser);
365
366
// When
367
User result = userService.createUser(testUser);
368
369
// Then
370
assertEquals(testUser, result);
371
verify(notificationService).sendWelcomeEmail(testUser);
372
}
373
}
374
```
375
376
### Error Handling
377
378
```java
379
@RunWith(VerboseMockitoJUnitRunner.class)
380
public class ErrorHandlingTest {
381
382
@Mock private ErrorProneService service;
383
384
@Test
385
public void testErrorScenarios() {
386
// Setup error conditions
387
when(service.process(anyString())).thenThrow(ProcessingException.class);
388
389
// Test error handling
390
assertThrows(ProcessingException.class, () -> {
391
service.process("test");
392
});
393
394
// VerboseMockitoJUnitRunner helps debug any issues
395
}
396
}
397
```
398
399
### Integration Testing
400
401
```java
402
@RunWith(SpringRunner.class)
403
@SpringBootTest
404
public class IntegrationTest {
405
406
@Rule
407
public MockitoRule mockitoRule = MockitoJUnit.rule();
408
409
@Autowired
410
private UserController userController;
411
412
@MockBean // Spring Boot's mock annotation
413
private UserService userService;
414
415
@Mock // Mockito's mock annotation
416
private ExternalApiClient apiClient;
417
418
@Test
419
public void testControllerIntegration() {
420
// Mix Spring integration testing with Mockito mocks
421
when(userService.findUser(1)).thenReturn(user);
422
423
ResponseEntity<User> response = userController.getUser(1);
424
425
assertEquals(HttpStatus.OK, response.getStatusCode());
426
assertEquals(user, response.getBody());
427
}
428
}
429
```
430
431
## Common Integration Issues
432
433
### Runner Conflicts
434
435
```java
436
// PROBLEM: Can't use multiple runners
437
@RunWith(MockitoJUnitRunner.class)
438
@RunWith(SpringRunner.class) // Compilation error
439
public class ConflictTest { }
440
441
// SOLUTION: Use rule instead
442
@RunWith(SpringRunner.class)
443
public class SolutionTest {
444
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
445
}
446
```
447
448
### Initialization Order
449
450
```java
451
// PROBLEM: Wrong initialization order
452
public class InitializationProblem extends BaseTest {
453
public InitializationProblem() {
454
MockitoAnnotations.initMocks(this); // Too early!
455
}
456
}
457
458
// SOLUTION: Use @Before or runner
459
@RunWith(MockitoJUnitRunner.class)
460
public class InitializationSolution extends BaseTest {
461
// Automatic initialization at right time
462
}
463
```
464
465
### Forgotten Initialization
466
467
```java
468
// PROBLEM: Mocks not initialized
469
public class ForgottenInitTest {
470
@Mock private Service service; // Will be null!
471
472
@Test
473
public void test() {
474
service.doSomething(); // NullPointerException
475
}
476
}
477
478
// SOLUTION: Add initialization
479
@RunWith(MockitoJUnitRunner.class)
480
public class ProperInitTest {
481
@Mock private Service service; // Properly initialized
482
}
483
```