0
# Partial Mocking
1
2
Partial mocking allows you to mock specific methods of a class while leaving other methods with their original implementation. This is essential for testing complex classes where you want to isolate specific behaviors without mocking the entire object.
3
4
## Capabilities
5
6
### Basic Partial Mocking by Method Names
7
8
Mock specific methods by name while keeping other methods intact.
9
10
```java { .api }
11
/**
12
* Mock several methods by name.
13
*
14
* @param type the type that'll be used to create a mock instance
15
* @param methodNames the names of the methods that should be mocked
16
* @return a mock object of type T
17
*/
18
public static synchronized <T> T createPartialMock(Class<T> type, String... methodNames);
19
20
/**
21
* Strictly mock several methods by name.
22
*
23
* @param type the type that'll be used to create a mock instance
24
* @param methodNames the names of the methods that should be mocked
25
* @return a mock object of type T
26
*/
27
public static synchronized <T> T createStrictPartialMock(Class<T> type, String... methodNames);
28
29
/**
30
* Nicely mock several methods by name.
31
*
32
* @param type the type that'll be used to create a mock instance
33
* @param methodNames the names of the methods that should be mocked
34
* @return a mock object of type T
35
*/
36
public static synchronized <T> T createNicePartialMock(Class<T> type, String... methodNames);
37
```
38
39
#### Usage Example
40
41
```java
42
import org.powermock.api.easymock.PowerMock;
43
import static org.easymock.EasyMock.expect;
44
45
public class PartialMockingTest {
46
47
@Test
48
public void testPartialMocking() {
49
// Only mock specific methods
50
UserService userService = PowerMock.createPartialMock(UserService.class, "validateUser", "logAccess");
51
52
// Set up expectations for mocked methods
53
expect(userService.validateUser("john.doe")).andReturn(true);
54
userService.logAccess("john.doe"); // void method expectation
55
PowerMock.expectLastCall();
56
57
PowerMock.replay(userService);
58
59
// This calls mocked validateUser and logAccess methods
60
boolean isValid = userService.validateUser("john.doe");
61
assertTrue(isValid);
62
63
// This calls the real implementation (not mocked)
64
String userInfo = userService.getUserInfo("john.doe"); // Real method behavior
65
assertNotNull(userInfo);
66
67
PowerMock.verify(userService);
68
}
69
}
70
```
71
72
### Inverse Partial Mocking (Mock All Except)
73
74
Mock all methods except the specified ones, useful when you want to keep only a few methods with real behavior.
75
76
```java { .api }
77
/**
78
* Mock all methods except the specified ones.
79
*
80
* @param type the type that'll be used to create a mock instance
81
* @param methodNames the names of the methods that should NOT be mocked
82
* @return a mock object of type T
83
*/
84
public static synchronized <T> T createPartialMockForAllMethodsExcept(Class<T> type, String... methodNames);
85
86
/**
87
* Mock all methods except the specified method with parameter types.
88
*
89
* @param type the type that'll be used to create a mock instance
90
* @param methodNameToExclude the name of the method that should NOT be mocked
91
* @param firstArgumentType the first argument type for the method to exclude
92
* @param moreTypes additional argument types for the method to exclude
93
* @return a mock object of type T
94
*/
95
public static synchronized <T> T createPartialMockForAllMethodsExcept(Class<T> type, String methodNameToExclude,
96
Class<?> firstArgumentType, Class<?>... moreTypes);
97
98
/**
99
* Strictly mock all methods except the specified ones.
100
*
101
* @param type the type that'll be used to create a mock instance
102
* @param methodNames the names of the methods that should NOT be mocked
103
* @return a mock object of type T
104
*/
105
public static synchronized <T> T createStrictPartialMockForAllMethodsExcept(Class<T> type, String... methodNames);
106
107
/**
108
* Nicely mock all methods except the specified ones.
109
*
110
* @param type the type that'll be used to create a mock instance
111
* @param methodNames the names of the methods that should NOT be mocked
112
* @return a mock object of type T
113
*/
114
public static synchronized <T> T createNicePartialMockForAllMethodsExcept(Class<T> type, String... methodNames);
115
```
116
117
#### Usage Example
118
119
```java
120
@Test
121
public void testInversePartialMocking() {
122
// Mock all methods EXCEPT getUserInfo and formatUserData
123
UserService userService = PowerMock.createPartialMockForAllMethodsExcept(
124
UserService.class, "getUserInfo", "formatUserData");
125
126
// Set up expectations for all mocked methods (everything except getUserInfo and formatUserData)
127
expect(userService.validateUser("jane.doe")).andReturn(true);
128
expect(userService.checkPermissions("jane.doe")).andReturn(true);
129
userService.logAccess("jane.doe");
130
PowerMock.expectLastCall();
131
132
PowerMock.replay(userService);
133
134
// These methods are mocked
135
boolean isValid = userService.validateUser("jane.doe");
136
boolean hasPermissions = userService.checkPermissions("jane.doe");
137
userService.logAccess("jane.doe");
138
139
// These methods use real implementation
140
String userInfo = userService.getUserInfo("jane.doe"); // Real behavior
141
String formatted = userService.formatUserData(userInfo); // Real behavior
142
143
assertTrue(isValid);
144
assertTrue(hasPermissions);
145
assertNotNull(userInfo);
146
assertNotNull(formatted);
147
148
PowerMock.verify(userService);
149
}
150
```
151
152
### Partial Mocking with Constructor Arguments
153
154
Create partial mocks that invoke specific constructors with arguments.
155
156
```java { .api }
157
/**
158
* Mock several methods with specific constructor invocation.
159
*
160
* @param type the type that'll be used to create a mock instance
161
* @param methodNames the names of the methods that should be mocked
162
* @param constructorArguments the constructor arguments
163
* @return a mock object of type T
164
*/
165
public static <T> T createPartialMock(Class<T> type, String[] methodNames, Object... constructorArguments);
166
167
/**
168
* Strictly mock several methods with specific constructor invocation.
169
*
170
* @param type the type that'll be used to create a mock instance
171
* @param methodNames the names of the methods that should be mocked
172
* @param constructorArguments the constructor arguments
173
* @return a mock object of type T
174
*/
175
public static <T> T createStrictPartialMock(Class<T> type, String[] methodNames, Object... constructorArguments);
176
177
/**
178
* Nicely mock several methods with specific constructor invocation.
179
*
180
* @param type the type that'll be used to create a mock instance
181
* @param methodNames the names of the methods that should be mocked
182
* @param constructorArguments the constructor arguments
183
* @return a mock object of type T
184
*/
185
public static <T> T createNicePartialMock(Class<T> type, String[] methodNames, Object... constructorArguments);
186
```
187
188
#### Usage Example
189
190
```java
191
@Test
192
public void testPartialMockWithConstructor() {
193
String[] methodsToMock = {"sendEmail", "logEmailSent"};
194
195
// Create partial mock with specific constructor arguments
196
EmailService emailService = PowerMock.createPartialMock(
197
EmailService.class, methodsToMock, "smtp.example.com", 587);
198
199
// Mock only the specified methods
200
expect(emailService.sendEmail("test@example.com", "Subject", "Body")).andReturn(true);
201
emailService.logEmailSent("test@example.com");
202
PowerMock.expectLastCall();
203
204
PowerMock.replay(emailService);
205
206
// Mocked methods
207
boolean sent = emailService.sendEmail("test@example.com", "Subject", "Body");
208
emailService.logEmailSent("test@example.com");
209
210
// Real implementation methods (initialized with constructor args)
211
String serverInfo = emailService.getServerInfo(); // Returns real server info
212
boolean isConnected = emailService.isConnected(); // Real connection check
213
214
assertTrue(sent);
215
assertEquals("smtp.example.com:587", serverInfo);
216
217
PowerMock.verify(emailService);
218
}
219
```
220
221
### Default Constructor Invocation
222
223
Create partial mocks that invoke the default constructor even if it's private.
224
225
```java { .api }
226
/**
227
* Mock several methods and invoke the default constructor.
228
*
229
* @param type the type of the mock object
230
* @param methodNames the names of the methods that should be mocked
231
* @return the mock object
232
* @throws Exception if constructor cannot be invoked
233
*/
234
public static <T> T createPartialMockAndInvokeDefaultConstructor(Class<T> type, String... methodNames) throws Exception;
235
236
/**
237
* Strictly mock several methods and invoke the default constructor.
238
*
239
* @param type the type of the mock object
240
* @param methodNames the names of the methods that should be mocked
241
* @return the mock object
242
* @throws Exception if constructor cannot be invoked
243
*/
244
public static <T> T createStrictPartialMockAndInvokeDefaultConstructor(Class<T> type, String... methodNames) throws Exception;
245
246
/**
247
* Nicely mock several methods and invoke the default constructor.
248
*
249
* @param type the type of the mock object
250
* @param methodNames the names of the methods that should be mocked
251
* @return the mock object
252
* @throws Exception if constructor cannot be invoked
253
*/
254
public static <T> T createNicePartialMockAndInvokeDefaultConstructor(Class<T> type, String... methodNames) throws Exception;
255
```
256
257
#### Usage Example
258
259
```java
260
@Test
261
public void testPartialMockWithDefaultConstructor() throws Exception {
262
// Create partial mock and invoke private default constructor
263
ConfigurationManager configManager = PowerMock.createPartialMockAndInvokeDefaultConstructor(
264
ConfigurationManager.class, "loadFromNetwork", "saveToNetwork");
265
266
// Mock network-related methods
267
expect(configManager.loadFromNetwork()).andReturn("network config data");
268
expect(configManager.saveToNetwork("updated config")).andReturn(true);
269
270
PowerMock.replay(configManager);
271
272
// Mocked network methods
273
String networkConfig = configManager.loadFromNetwork();
274
boolean saved = configManager.saveToNetwork("updated config");
275
276
// Real implementation methods (using initialized state from constructor)
277
String localConfig = configManager.loadFromLocal(); // Real behavior
278
Map<String, String> allConfigs = configManager.getAllConfigs(); // Real behavior
279
280
assertEquals("network config data", networkConfig);
281
assertTrue(saved);
282
assertNotNull(localConfig);
283
assertNotNull(allConfigs);
284
285
PowerMock.verify(configManager);
286
}
287
```
288
289
### Overloaded Method Partial Mocking
290
291
Handle overloaded methods by specifying parameter types for precise method selection.
292
293
```java { .api }
294
/**
295
* Mock a single specific method using parameter types.
296
*
297
* @param type the type that'll be used to create a mock instance
298
* @param methodNameToMock the name of the method to mock
299
* @param firstArgumentType the type of the first parameter
300
* @param additionalArgumentTypes optionally more parameter types
301
* @return a mock object of type T
302
*/
303
public static synchronized <T> T createPartialMock(Class<T> type, String methodNameToMock,
304
Class<?> firstArgumentType, Class<?>... additionalArgumentTypes);
305
306
/**
307
* Mock overloaded methods with explicit parameter types and constructor arguments.
308
*
309
* @param type the type that'll be used to create a mock instance
310
* @param methodName the name of the method to mock
311
* @param methodParameterTypes parameter types that define the method
312
* @param constructorArguments the constructor arguments
313
* @return a mock object of type T
314
*/
315
public static <T> T createPartialMock(Class<T> type, String methodName, Class<?>[] methodParameterTypes,
316
Object... constructorArguments);
317
```
318
319
#### Usage Example
320
321
```java
322
@Test
323
public void testOverloadedMethodPartialMocking() {
324
// Mock specific overloaded method: processData(String, boolean)
325
DataProcessor processor = PowerMock.createPartialMock(
326
DataProcessor.class, "processData", String.class, boolean.class);
327
328
expect(processor.processData("test data", true)).andReturn("processed with validation");
329
330
PowerMock.replay(processor);
331
332
// This call uses the mocked version: processData(String, boolean)
333
String result1 = processor.processData("test data", true);
334
335
// This call uses real implementation: processData(String)
336
String result2 = processor.processData("test data");
337
338
// This call uses real implementation: processData(byte[])
339
String result3 = processor.processData("test data".getBytes());
340
341
assertEquals("processed with validation", result1);
342
assertNotNull(result2); // Real implementation result
343
assertNotNull(result3); // Real implementation result
344
345
PowerMock.verify(processor);
346
}
347
```
348
349
### Class Hierarchy Partial Mocking
350
351
Mock methods at specific levels in the class inheritance hierarchy.
352
353
```java { .api }
354
/**
355
* Mock methods at a specific place in the class hierarchy.
356
*
357
* @param type the type that'll be used to create a mock instance
358
* @param where where in the class hierarchy the methods reside
359
* @param methodNames the names of the methods that should be mocked
360
* @return a mock object of type T
361
*/
362
public static synchronized <T> T createPartialMock(Class<T> type, Class<? super T> where, String... methodNames);
363
364
/**
365
* Strictly mock methods at a specific place in the class hierarchy.
366
*
367
* @param type the type that'll be used to create a mock instance
368
* @param where where in the class hierarchy the methods reside
369
* @param methodNames the names of the methods that should be mocked
370
* @return a mock object of type T
371
*/
372
public static synchronized <T> T createStrictPartialMock(Class<T> type, Class<? super T> where, String... methodNames);
373
374
/**
375
* Nicely mock methods at a specific place in the class hierarchy.
376
*
377
* @param type the type that'll be used to create a mock instance
378
* @param where where in the class hierarchy the methods reside
379
* @param methodNames the names of the methods that should be mocked
380
* @return a mock object of type T
381
*/
382
public static synchronized <T> T createNicePartialMock(Class<T> type, Class<? super T> where, String... methodNames);
383
```
384
385
#### Usage Example
386
387
```java
388
class BaseValidator {
389
protected boolean validateFormat(String input) {
390
return input != null && input.length() > 0;
391
}
392
393
protected String formatError(String message) {
394
return "Error: " + message;
395
}
396
}
397
398
class EmailValidator extends BaseValidator {
399
@Override
400
protected boolean validateFormat(String email) {
401
return email.contains("@");
402
}
403
404
public ValidationResult validate(String email) {
405
// Uses validateFormat and formatError methods
406
if (validateFormat(email)) {
407
return ValidationResult.success();
408
} else {
409
return ValidationResult.failure(formatError("Invalid email format"));
410
}
411
}
412
}
413
414
@Test
415
public void testHierarchyPartialMocking() {
416
// Mock only the base class method, not the overridden one
417
EmailValidator validator = PowerMock.createPartialMock(
418
EmailValidator.class, BaseValidator.class, "formatError");
419
420
expect(validator.formatError("Invalid email format")).andReturn("Custom error message");
421
422
PowerMock.replay(validator);
423
424
// This uses the real overridden validateFormat method in EmailValidator
425
// But uses the mocked formatError method from BaseValidator
426
ValidationResult result = validator.validate("invalid-email");
427
428
assertFalse(result.isValid());
429
assertEquals("Custom error message", result.getErrorMessage());
430
431
PowerMock.verify(validator);
432
}
433
```
434
435
## Advanced Partial Mocking Patterns
436
437
### Combining Multiple Partial Mocking Strategies
438
439
```java
440
@Test
441
public void testCombinedPartialMocking() throws Exception {
442
// Create partial mock with constructor, excluding some methods
443
String[] excludedMethods = {"calculateTotal", "formatOutput"};
444
OrderProcessor processor = PowerMock.createPartialMockForAllMethodsExcept(
445
OrderProcessor.class, excludedMethods);
446
447
// Mock the methods that aren't excluded
448
expect(processor.validateOrder(anyObject(Order.class))).andReturn(true);
449
expect(processor.applyDiscounts(anyObject(Order.class))).andReturn(new BigDecimal("10.00"));
450
processor.logProcessing(anyObject(Order.class));
451
PowerMock.expectLastCall();
452
453
PowerMock.replay(processor);
454
455
Order order = new Order("item1", new BigDecimal("100.00"));
456
457
// This uses mocked methods and real calculateTotal/formatOutput
458
String result = processor.processOrder(order);
459
460
assertNotNull(result);
461
assertTrue(result.contains("90.00")); // Real calculateTotal: 100 - 10 = 90
462
463
PowerMock.verify(processor);
464
}
465
```
466
467
### Testing Protected Methods
468
469
```java
470
@Test
471
public void testProtectedMethodPartialMocking() {
472
DatabaseService dbService = PowerMock.createPartialMock(DatabaseService.class, "executeQuery");
473
474
// Mock protected method
475
expect(dbService.executeQuery("SELECT * FROM users")).andReturn("query result");
476
477
PowerMock.replay(dbService);
478
479
// Public method calls protected executeQuery internally
480
String result = dbService.getUsers();
481
482
assertEquals("processed: query result", result);
483
PowerMock.verify(dbService);
484
}
485
```
486
487
## Important Notes
488
489
### Method Name Matching
490
491
PowerMock matches methods by name, so all overloaded methods with the same name will be mocked unless you specify parameter types explicitly.
492
493
### Final Method Support
494
495
Partial mocking works with final methods, which is not possible with standard mocking frameworks:
496
497
```java
498
final class FinalService {
499
public final String processData(String data) {
500
return data.toUpperCase();
501
}
502
503
public final void logData(String data) {
504
System.out.println("Logging: " + data);
505
}
506
}
507
508
// This works with PowerMock
509
FinalService service = PowerMock.createPartialMock(FinalService.class, "logData");
510
```
511
512
### Integration with Full Mocks
513
514
Partial mocks can be used alongside full mocks in the same test, providing flexibility in testing complex object interactions.