0
# Private Method Testing
1
2
PowerMock enables testing of private method behavior through expectation setup and verification. This capability is essential for testing internal class logic, method interactions, and complex private method workflows without exposing implementation details through public APIs.
3
4
## Capabilities
5
6
### Basic Private Method Expectations
7
8
Set up expectations for private method calls using method names and arguments.
9
10
```java { .api }
11
/**
12
* Used to specify expectations on private methods using the method name.
13
*
14
* @param instance the object instance containing the private method
15
* @param methodName the name of the private method
16
* @param arguments the method arguments
17
* @return expectation setter for further configuration
18
* @throws Exception if method cannot be found or invoked
19
*/
20
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, String methodName, Object... arguments) throws Exception;
21
22
/**
23
* Used to specify expectations on private methods without specifying a method name.
24
* PowerMock tries to find a unique method based on argument parameters.
25
*
26
* @param instance the object instance containing the private method
27
* @param arguments the method arguments
28
* @return expectation setter for further configuration
29
* @throws Exception if method cannot be found or invoked
30
*/
31
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, Object... arguments) throws Exception;
32
```
33
34
#### Usage Example
35
36
```java
37
import org.powermock.api.easymock.PowerMock;
38
import org.powermock.reflect.Whitebox;
39
40
public class PrivateMethodTest {
41
42
@Test
43
public void testPrivateMethodExpectation() throws Exception {
44
UserService userService = PowerMock.createPartialMock(UserService.class, "validateUser");
45
46
// Set up expectation for private method call
47
PowerMock.expectPrivate(userService, "validateUser", "john.doe")
48
.andReturn(true);
49
50
PowerMock.replay(userService);
51
52
// Call public method that internally calls private validateUser method
53
boolean result = userService.authenticateUser("john.doe", "password123");
54
55
assertTrue(result);
56
PowerMock.verify(userService);
57
}
58
59
@Test
60
public void testPrivateMethodWithoutName() throws Exception {
61
Calculator calculator = PowerMock.createPartialMock(Calculator.class, "computeInternal");
62
63
// PowerMock finds method based on argument types
64
PowerMock.expectPrivate(calculator, 5, 3) // Finds method with (int, int) signature
65
.andReturn(8);
66
67
PowerMock.replay(calculator);
68
69
int result = calculator.add(5, 3); // Calls private computeInternal(5, 3)
70
71
assertEquals(8, result);
72
PowerMock.verify(calculator);
73
}
74
}
75
```
76
77
### Method Object-Based Expectations
78
79
Set up expectations using Method objects for precise method identification.
80
81
```java { .api }
82
/**
83
* Used to specify expectations on private methods using Method objects.
84
*
85
* @param instance the object instance containing the private method
86
* @param method the Method object representing the private method
87
* @param arguments the method arguments
88
* @return expectation setter for further configuration
89
* @throws Exception if method cannot be invoked
90
*/
91
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, Method method, Object... arguments) throws Exception;
92
93
/**
94
* Used to specify expectations on private static methods using Method objects.
95
*
96
* @param clazz the class containing the private static method
97
* @param method the Method object representing the private static method
98
* @param arguments the method arguments
99
* @return expectation setter for further configuration
100
* @throws Exception if method cannot be invoked
101
*/
102
public static synchronized <T> IExpectationSetters<T> expectPrivate(Class<?> clazz, Method method, Object... arguments) throws Exception;
103
```
104
105
#### Usage Example
106
107
```java
108
@Test
109
public void testPrivateMethodWithMethodObject() throws Exception {
110
SecurityManager securityManager = PowerMock.createPartialMock(SecurityManager.class, "checkPermissions");
111
112
// Get the private method using reflection
113
Method checkPermissionsMethod = Whitebox.getMethod(SecurityManager.class, "checkPermissions", String.class, User.class);
114
115
User testUser = new User("testuser");
116
PowerMock.expectPrivate(securityManager, checkPermissionsMethod, "read", testUser)
117
.andReturn(true);
118
119
PowerMock.replay(securityManager);
120
121
boolean hasAccess = securityManager.hasReadAccess("read", testUser);
122
123
assertTrue(hasAccess);
124
PowerMock.verify(securityManager);
125
}
126
```
127
128
### Overloaded Private Method Expectations
129
130
Handle overloaded private methods by specifying parameter types explicitly.
131
132
```java { .api }
133
/**
134
* Used to specify expectations on overloaded private methods.
135
*
136
* @param instance the object instance containing the private method
137
* @param methodName the name of the private method
138
* @param parameterTypes the parameter types to distinguish overloaded methods
139
* @param arguments the method arguments
140
* @return expectation setter for further configuration
141
* @throws Exception if method cannot be found or invoked
142
*/
143
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, String methodName,
144
Class<?>[] parameterTypes, Object... arguments) throws Exception;
145
```
146
147
#### Usage Example
148
149
```java
150
@Test
151
public void testOverloadedPrivateMethods() throws Exception {
152
DataProcessor processor = PowerMock.createPartialMock(DataProcessor.class, "processData");
153
154
// Handle overloaded private methods by specifying parameter types
155
Class<?>[] stringArrayType = {String[].class};
156
Class<?>[] listType = {List.class};
157
158
String[] stringData = {"a", "b", "c"};
159
List<String> listData = Arrays.asList("x", "y", "z");
160
161
// Set up expectations for different overloaded methods
162
PowerMock.expectPrivate(processor, "processData", stringArrayType, new Object[]{stringData})
163
.andReturn("array-processed");
164
165
PowerMock.expectPrivate(processor, "processData", listType, listData)
166
.andReturn("list-processed");
167
168
PowerMock.replay(processor);
169
170
String result1 = processor.handleArrayData(stringData); // Calls processData(String[])
171
String result2 = processor.handleListData(listData); // Calls processData(List)
172
173
assertEquals("array-processed", result1);
174
assertEquals("list-processed", result2);
175
PowerMock.verify(processor);
176
}
177
```
178
179
### Class Hierarchy Private Method Expectations
180
181
Specify private method expectations at specific levels in the class hierarchy.
182
183
```java { .api }
184
/**
185
* Used to specify expectations for private methods at a specific place in the class hierarchy.
186
*
187
* @param instance the object instance containing the private method
188
* @param methodName the name of the private method
189
* @param where the class in the hierarchy where the method is defined
190
* @param arguments the method arguments
191
* @return expectation setter for further configuration
192
* @throws Exception if method cannot be found or invoked
193
*/
194
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, String methodName,
195
Class<?> where, Object... arguments) throws Exception;
196
197
/**
198
* Used to specify expectations for overloaded private methods at a specific place in the class hierarchy.
199
*
200
* @param instance the object instance containing the private method
201
* @param methodName the name of the private method
202
* @param where the class in the hierarchy where the method is defined
203
* @param parameterTypes the parameter types to distinguish overloaded methods
204
* @param arguments the method arguments
205
* @return expectation setter for further configuration
206
* @throws Exception if method cannot be found or invoked
207
*/
208
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, String methodName,
209
Class<?> where, Class<?>[] parameterTypes, Object... arguments) throws Exception;
210
```
211
212
#### Usage Example
213
214
```java
215
class BaseService {
216
private String formatMessage(String msg) {
217
return "Base: " + msg;
218
}
219
}
220
221
class ExtendedService extends BaseService {
222
private String formatMessage(String msg) {
223
return "Extended: " + msg;
224
}
225
226
public String processMessage(String msg) {
227
// Calls private method - but which one?
228
return formatMessage(msg);
229
}
230
}
231
232
@Test
233
public void testPrivateMethodInHierarchy() throws Exception {
234
ExtendedService service = PowerMock.createPartialMock(ExtendedService.class, "formatMessage");
235
236
// Specify which class's private method to mock
237
PowerMock.expectPrivate(service, "formatMessage", BaseService.class, "test")
238
.andReturn("Mocked base message");
239
240
PowerMock.expectPrivate(service, "formatMessage", ExtendedService.class, "test")
241
.andReturn("Mocked extended message");
242
243
PowerMock.replay(service);
244
245
String result = service.processMessage("test");
246
247
assertEquals("Mocked extended message", result); // Uses ExtendedService's method
248
PowerMock.verify(service);
249
}
250
```
251
252
## Advanced Private Method Testing
253
254
### Testing Private Method Side Effects
255
256
Verify that private methods are called with expected parameters and frequencies.
257
258
```java
259
@Test
260
public void testPrivateMethodSideEffects() throws Exception {
261
AuditLogger logger = PowerMock.createPartialMock(AuditLogger.class, "writeToFile");
262
263
// Expect private method to be called twice with different parameters
264
PowerMock.expectPrivate(logger, "writeToFile", "login", "user1").once();
265
PowerMock.expectPrivate(logger, "writeToFile", "logout", "user1").once();
266
267
PowerMock.replay(logger);
268
269
// Public methods that internally call private writeToFile method
270
logger.logUserLogin("user1");
271
logger.logUserLogout("user1");
272
273
PowerMock.verify(logger); // Verifies both private method calls occurred
274
}
275
```
276
277
### Exception Handling in Private Methods
278
279
Set up private method expectations to throw exceptions.
280
281
```java
282
@Test(expected = ProcessingException.class)
283
public void testPrivateMethodThrowsException() throws Exception {
284
FileManager fileManager = PowerMock.createPartialMock(FileManager.class, "validatePath");
285
286
PowerMock.expectPrivate(fileManager, "validatePath", "/invalid/path")
287
.andThrow(new ProcessingException("Invalid path"));
288
289
PowerMock.replay(fileManager);
290
291
fileManager.openFile("/invalid/path"); // Calls private validatePath method
292
293
// Test expects ProcessingException to be thrown
294
}
295
```
296
297
### Integration with Whitebox Testing
298
299
Combine private method expectations with direct private method invocation testing.
300
301
```java
302
@Test
303
public void testPrivateMethodDirectly() throws Exception {
304
CryptoService cryptoService = new CryptoService();
305
306
// Test private method directly using Whitebox
307
String result = Whitebox.invokeMethod(cryptoService, "generateSalt", 16);
308
assertNotNull(result);
309
assertEquals(16, result.length());
310
311
// Also test through partial mocking
312
CryptoService mockCrypto = PowerMock.createPartialMock(CryptoService.class, "generateSalt");
313
PowerMock.expectPrivate(mockCrypto, "generateSalt", 16).andReturn("fixed-salt-value");
314
PowerMock.replay(mockCrypto);
315
316
String encryptedData = mockCrypto.encryptData("secret"); // Uses mocked generateSalt
317
assertTrue(encryptedData.contains("fixed-salt-value"));
318
319
PowerMock.verify(mockCrypto);
320
}
321
```
322
323
## Important Notes
324
325
### Partial Mocking Requirement
326
327
To set up expectations for private methods, you must create a partial mock that includes the private method names:
328
329
```java
330
// Correct: Include private method in partial mock
331
MyService service = PowerMock.createPartialMock(MyService.class, "privateMethod");
332
333
// Incorrect: Full mock doesn't allow private method expectations
334
MyService service = PowerMock.createMock(MyService.class); // Won't work for private methods
335
```
336
337
### Method Visibility
338
339
PowerMock can access private methods from any visibility level:
340
- `private` - Standard private methods
341
- `protected` - Protected methods accessible in subclasses
342
- Package-private - Methods with no access modifier
343
344
### Static Private Methods
345
346
Private static methods are handled similarly but use the class instead of instance:
347
348
```java
349
PowerMock.expectPrivate(MyUtilClass.class, "privateStaticMethod", "param")
350
.andReturn("result");
351
```