PowerMock API extension for Mockito that enables mocking of static methods, constructors, final classes and methods, private methods, and advanced testing capabilities through bytecode manipulation and custom classloading
—
PowerMock enables stubbing and verification of private method calls, allowing comprehensive testing of internal implementation details when necessary. This capability is essential for testing legacy code where private methods contain critical business logic that cannot be easily extracted.
Stub private instance methods by specifying the method name and arguments.
static <T> OngoingStubbing<T> when(Object instance, String methodName, Object... arguments) throws Exception;Parameters:
instance - The object instance containing the private methodmethodName - Name of the private method to stubarguments - Arguments to match for the method callReturns: OngoingStubbing for chaining return values or exceptions
Usage Example:
@Test
@PrepareForTest(UserService.class)
public void testPrivateMethodStubbing() throws Exception {
UserService service = spy(new UserService());
// Stub private validation method
when(service, "validateUser", "john@example.com").thenReturn(true);
when(service, "validateUser", "invalid-email").thenReturn(false);
// Test public method that uses private validation
boolean validResult = service.registerUser("john@example.com", "password");
boolean invalidResult = service.registerUser("invalid-email", "password");
assertTrue(validResult);
assertFalse(invalidResult);
}Stub private instance methods using Method reflection objects for type safety.
static <T> WithOrWithoutExpectedArguments<T> when(Object instance, Method method) throws Exception;Parameters:
instance - The object instance containing the private methodmethod - Method reflection object for the private methodReturns: Fluent interface for specifying arguments and return values
Usage Example:
@Test
@PrepareForTest(OrderProcessor.class)
public void testPrivateMethodByReflection() throws Exception {
OrderProcessor processor = spy(new OrderProcessor());
Method validateMethod = OrderProcessor.class.getDeclaredMethod("validateOrder", Order.class);
// Stub using method reference
when(processor, validateMethod).withArguments(any(Order.class)).thenReturn(true);
Order order = new Order("item1", 100.0);
boolean result = processor.processOrder(order);
assertTrue(result);
}Stub private static methods on classes using Method reflection.
static <T> WithOrWithoutExpectedArguments<T> when(Class<?> cls, Method method) throws Exception;Parameters:
cls - The class containing the private static methodmethod - Method reflection object for the private static methodReturns: Fluent interface for specifying arguments and return values
Usage Example:
@Test
@PrepareForTest(SecurityUtils.class)
public void testPrivateStaticMethod() throws Exception {
Method encryptMethod = SecurityUtils.class.getDeclaredMethod("encryptInternal", String.class);
when(SecurityUtils.class, encryptMethod)
.withArguments("sensitive")
.thenReturn("encrypted-sensitive");
String result = SecurityUtils.encrypt("sensitive");
assertEquals("encrypted-sensitive", result);
}Stub private methods by providing parameters without specifying the method name, using parameter types for method resolution.
static <T> OngoingStubbing<T> when(Object instance, Object... arguments) throws Exception;Parameters:
instance - The object instance containing the private methodarguments - Arguments that determine which private method to stubReturns: OngoingStubbing for chaining return values or exceptions
Usage Example:
@Test
@PrepareForTest(CalculatorService.class)
public void testPrivateMethodByParameters() throws Exception {
CalculatorService calculator = spy(new CalculatorService());
// Stub private method based on parameter types and values
when(calculator, 5.0, 3.0).thenReturn(8.0); // Assumes private method with (double, double)
double result = calculator.performComplexCalculation(5.0, 3.0);
assertEquals(8.0, result, 0.001);
}Stub private static methods by specifying the class, method name, and arguments.
static <T> OngoingStubbing<T> when(Class<?> clazz, String methodToExpect, Object... arguments) throws Exception;Parameters:
clazz - The class containing the private static methodmethodToExpect - Name of the private static method to stubarguments - Arguments to match for the method callReturns: OngoingStubbing for chaining return values or exceptions
Usage Example:
@Test
@PrepareForTest(ConfigurationHelper.class)
public void testPrivateStaticMethodByName() throws Exception {
when(ConfigurationHelper.class, "loadConfigFromFile", "config.properties")
.thenReturn(mockProperties);
Properties result = ConfigurationHelper.getConfiguration("config.properties");
assertEquals(mockProperties, result);
}Stub private static methods using parameter matching without specifying method names.
static <T> OngoingStubbing<T> when(Class<?> klass, Object... arguments) throws Exception;Parameters:
klass - The class containing the private static methodarguments - Arguments that determine which private static method to stubReturns: OngoingStubbing for chaining return values or exceptions
Usage Example:
@Test
@PrepareForTest(NetworkUtils.class)
public void testPrivateStaticByParams() throws Exception {
when(NetworkUtils.class, "192.168.1.1", 8080).thenReturn(true);
boolean isReachable = NetworkUtils.checkConnection("192.168.1.1", 8080);
assertTrue(isReachable);
}Delegates to standard Mockito when() for regular (non-private) method stubbing within PowerMock tests.
static <T> OngoingStubbing<T> when(T methodCall);Parameters:
methodCall - The method call to stub (standard Mockito syntax)Returns: OngoingStubbing for chaining return values or exceptions
Usage Example:
@Test
@PrepareForTest(DatabaseService.class)
public void testCombinedStubbing() throws Exception {
DatabaseService service = spy(new DatabaseService());
Connection mockConnection = mock(Connection.class);
// Standard Mockito stubbing for public methods
when(service.getConnection()).thenReturn(mockConnection);
// PowerMock stubbing for private methods
when(service, "validateConnection", mockConnection).thenReturn(true);
boolean result = service.performQuery("SELECT * FROM users");
assertTrue(result);
}Verify that private methods were called with expected arguments and frequencies.
static PrivateMethodVerification verifyPrivate(Object object) throws Exception;
static PrivateMethodVerification verifyPrivate(Object object, VerificationMode verificationMode) throws Exception;
static PrivateMethodVerification verifyPrivate(Class<?> clazz) throws Exception;
static PrivateMethodVerification verifyPrivate(Class<?> clazz, VerificationMode verificationMode) throws Exception;Parameters:
object/clazz - The instance or class containing the private methodverificationMode - Verification mode (times, atLeast, never, etc.)Returns: PrivateMethodVerification for specifying the method to verify
Usage Example:
@Test
@PrepareForTest(EmailService.class)
public void testPrivateMethodVerification() throws Exception {
EmailService service = spy(new EmailService());
service.sendWelcomeEmail("user@example.com");
// Verify private method was called
verifyPrivate(service).invoke("validateEmailFormat", "user@example.com");
verifyPrivate(service, times(1)).invoke("logEmailActivity", anyString());
}interface PrivateMethodVerification {
void invoke(Object... arguments) throws Exception;
WithOrWithoutVerifiedArguments invoke(Method method) throws Exception;
void invoke(String methodToVerify, Object... arguments) throws Exception;
}@Test
@PrepareForTest(LoanCalculator.class)
public void testPrivateBusinessLogic() throws Exception {
LoanCalculator calculator = spy(new LoanCalculator());
// Stub private risk assessment method
when(calculator, "assessCreditRisk", any(CreditProfile.class)).thenReturn(RiskLevel.LOW);
CreditProfile profile = new CreditProfile(750, 50000, 5000);
LoanOffer offer = calculator.calculateLoanOffer(profile);
// Verify the private method was used in calculation
verifyPrivate(calculator).invoke("assessCreditRisk", profile);
assertEquals(5.5, offer.getInterestRate(), 0.1);
}@Test
@PrepareForTest(PasswordValidator.class)
public void testPrivateValidation() throws Exception {
PasswordValidator validator = spy(new PasswordValidator());
// Test each private validation rule separately
when(validator, "checkLength", "short").thenReturn(false);
when(validator, "checkComplexity", "simple123").thenReturn(false);
when(validator, "checkLength", "properLength123!").thenReturn(true);
when(validator, "checkComplexity", "properLength123!").thenReturn(true);
boolean weakResult = validator.isValidPassword("short");
boolean strongResult = validator.isValidPassword("properLength123!");
assertFalse(weakResult);
assertTrue(strongResult);
verifyPrivate(validator).invoke("checkLength", "short");
verifyPrivate(validator).invoke("checkComplexity", "properLength123!");
}@Test
@PrepareForTest(DataProcessor.class)
public void testPrivateErrorHandling() throws Exception {
DataProcessor processor = spy(new DataProcessor());
// Stub private error recovery method
when(processor, "recoverFromError", any(Exception.class)).thenReturn("recovered-data");
// Test error scenario triggers private recovery
String result = processor.processData("corrupted-input");
assertEquals("recovered-data", result);
verifyPrivate(processor).invoke("recoverFromError", any(ProcessingException.class));
}@PrepareForTest annotation@RunWith(PowerMockRunner.class) or equivalentInstall with Tessl CLI
npx tessl i tessl/maven-org-powermock--powermock-api-mockito