PowerMock API extension for EasyMock providing advanced mocking capabilities for static methods, constructors, final classes, and private methods through bytecode manipulation.
—
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.
Mock specific methods by name while keeping other methods intact.
/**
* Mock several methods by name.
*
* @param type the type that'll be used to create a mock instance
* @param methodNames the names of the methods that should be mocked
* @return a mock object of type T
*/
public static synchronized <T> T createPartialMock(Class<T> type, String... methodNames);
/**
* Strictly mock several methods by name.
*
* @param type the type that'll be used to create a mock instance
* @param methodNames the names of the methods that should be mocked
* @return a mock object of type T
*/
public static synchronized <T> T createStrictPartialMock(Class<T> type, String... methodNames);
/**
* Nicely mock several methods by name.
*
* @param type the type that'll be used to create a mock instance
* @param methodNames the names of the methods that should be mocked
* @return a mock object of type T
*/
public static synchronized <T> T createNicePartialMock(Class<T> type, String... methodNames);import org.powermock.api.easymock.PowerMock;
import static org.easymock.EasyMock.expect;
public class PartialMockingTest {
@Test
public void testPartialMocking() {
// Only mock specific methods
UserService userService = PowerMock.createPartialMock(UserService.class, "validateUser", "logAccess");
// Set up expectations for mocked methods
expect(userService.validateUser("john.doe")).andReturn(true);
userService.logAccess("john.doe"); // void method expectation
PowerMock.expectLastCall();
PowerMock.replay(userService);
// This calls mocked validateUser and logAccess methods
boolean isValid = userService.validateUser("john.doe");
assertTrue(isValid);
// This calls the real implementation (not mocked)
String userInfo = userService.getUserInfo("john.doe"); // Real method behavior
assertNotNull(userInfo);
PowerMock.verify(userService);
}
}Mock all methods except the specified ones, useful when you want to keep only a few methods with real behavior.
/**
* Mock all methods except the specified ones.
*
* @param type the type that'll be used to create a mock instance
* @param methodNames the names of the methods that should NOT be mocked
* @return a mock object of type T
*/
public static synchronized <T> T createPartialMockForAllMethodsExcept(Class<T> type, String... methodNames);
/**
* Mock all methods except the specified method with parameter types.
*
* @param type the type that'll be used to create a mock instance
* @param methodNameToExclude the name of the method that should NOT be mocked
* @param firstArgumentType the first argument type for the method to exclude
* @param moreTypes additional argument types for the method to exclude
* @return a mock object of type T
*/
public static synchronized <T> T createPartialMockForAllMethodsExcept(Class<T> type, String methodNameToExclude,
Class<?> firstArgumentType, Class<?>... moreTypes);
/**
* Strictly mock all methods except the specified ones.
*
* @param type the type that'll be used to create a mock instance
* @param methodNames the names of the methods that should NOT be mocked
* @return a mock object of type T
*/
public static synchronized <T> T createStrictPartialMockForAllMethodsExcept(Class<T> type, String... methodNames);
/**
* Nicely mock all methods except the specified ones.
*
* @param type the type that'll be used to create a mock instance
* @param methodNames the names of the methods that should NOT be mocked
* @return a mock object of type T
*/
public static synchronized <T> T createNicePartialMockForAllMethodsExcept(Class<T> type, String... methodNames);@Test
public void testInversePartialMocking() {
// Mock all methods EXCEPT getUserInfo and formatUserData
UserService userService = PowerMock.createPartialMockForAllMethodsExcept(
UserService.class, "getUserInfo", "formatUserData");
// Set up expectations for all mocked methods (everything except getUserInfo and formatUserData)
expect(userService.validateUser("jane.doe")).andReturn(true);
expect(userService.checkPermissions("jane.doe")).andReturn(true);
userService.logAccess("jane.doe");
PowerMock.expectLastCall();
PowerMock.replay(userService);
// These methods are mocked
boolean isValid = userService.validateUser("jane.doe");
boolean hasPermissions = userService.checkPermissions("jane.doe");
userService.logAccess("jane.doe");
// These methods use real implementation
String userInfo = userService.getUserInfo("jane.doe"); // Real behavior
String formatted = userService.formatUserData(userInfo); // Real behavior
assertTrue(isValid);
assertTrue(hasPermissions);
assertNotNull(userInfo);
assertNotNull(formatted);
PowerMock.verify(userService);
}Create partial mocks that invoke specific constructors with arguments.
/**
* Mock several methods with specific constructor invocation.
*
* @param type the type that'll be used to create a mock instance
* @param methodNames the names of the methods that should be mocked
* @param constructorArguments the constructor arguments
* @return a mock object of type T
*/
public static <T> T createPartialMock(Class<T> type, String[] methodNames, Object... constructorArguments);
/**
* Strictly mock several methods with specific constructor invocation.
*
* @param type the type that'll be used to create a mock instance
* @param methodNames the names of the methods that should be mocked
* @param constructorArguments the constructor arguments
* @return a mock object of type T
*/
public static <T> T createStrictPartialMock(Class<T> type, String[] methodNames, Object... constructorArguments);
/**
* Nicely mock several methods with specific constructor invocation.
*
* @param type the type that'll be used to create a mock instance
* @param methodNames the names of the methods that should be mocked
* @param constructorArguments the constructor arguments
* @return a mock object of type T
*/
public static <T> T createNicePartialMock(Class<T> type, String[] methodNames, Object... constructorArguments);@Test
public void testPartialMockWithConstructor() {
String[] methodsToMock = {"sendEmail", "logEmailSent"};
// Create partial mock with specific constructor arguments
EmailService emailService = PowerMock.createPartialMock(
EmailService.class, methodsToMock, "smtp.example.com", 587);
// Mock only the specified methods
expect(emailService.sendEmail("test@example.com", "Subject", "Body")).andReturn(true);
emailService.logEmailSent("test@example.com");
PowerMock.expectLastCall();
PowerMock.replay(emailService);
// Mocked methods
boolean sent = emailService.sendEmail("test@example.com", "Subject", "Body");
emailService.logEmailSent("test@example.com");
// Real implementation methods (initialized with constructor args)
String serverInfo = emailService.getServerInfo(); // Returns real server info
boolean isConnected = emailService.isConnected(); // Real connection check
assertTrue(sent);
assertEquals("smtp.example.com:587", serverInfo);
PowerMock.verify(emailService);
}Create partial mocks that invoke the default constructor even if it's private.
/**
* Mock several methods and invoke the default constructor.
*
* @param type the type of the mock object
* @param methodNames the names of the methods that should be mocked
* @return the mock object
* @throws Exception if constructor cannot be invoked
*/
public static <T> T createPartialMockAndInvokeDefaultConstructor(Class<T> type, String... methodNames) throws Exception;
/**
* Strictly mock several methods and invoke the default constructor.
*
* @param type the type of the mock object
* @param methodNames the names of the methods that should be mocked
* @return the mock object
* @throws Exception if constructor cannot be invoked
*/
public static <T> T createStrictPartialMockAndInvokeDefaultConstructor(Class<T> type, String... methodNames) throws Exception;
/**
* Nicely mock several methods and invoke the default constructor.
*
* @param type the type of the mock object
* @param methodNames the names of the methods that should be mocked
* @return the mock object
* @throws Exception if constructor cannot be invoked
*/
public static <T> T createNicePartialMockAndInvokeDefaultConstructor(Class<T> type, String... methodNames) throws Exception;@Test
public void testPartialMockWithDefaultConstructor() throws Exception {
// Create partial mock and invoke private default constructor
ConfigurationManager configManager = PowerMock.createPartialMockAndInvokeDefaultConstructor(
ConfigurationManager.class, "loadFromNetwork", "saveToNetwork");
// Mock network-related methods
expect(configManager.loadFromNetwork()).andReturn("network config data");
expect(configManager.saveToNetwork("updated config")).andReturn(true);
PowerMock.replay(configManager);
// Mocked network methods
String networkConfig = configManager.loadFromNetwork();
boolean saved = configManager.saveToNetwork("updated config");
// Real implementation methods (using initialized state from constructor)
String localConfig = configManager.loadFromLocal(); // Real behavior
Map<String, String> allConfigs = configManager.getAllConfigs(); // Real behavior
assertEquals("network config data", networkConfig);
assertTrue(saved);
assertNotNull(localConfig);
assertNotNull(allConfigs);
PowerMock.verify(configManager);
}Handle overloaded methods by specifying parameter types for precise method selection.
/**
* Mock a single specific method using parameter types.
*
* @param type the type that'll be used to create a mock instance
* @param methodNameToMock the name of the method to mock
* @param firstArgumentType the type of the first parameter
* @param additionalArgumentTypes optionally more parameter types
* @return a mock object of type T
*/
public static synchronized <T> T createPartialMock(Class<T> type, String methodNameToMock,
Class<?> firstArgumentType, Class<?>... additionalArgumentTypes);
/**
* Mock overloaded methods with explicit parameter types and constructor arguments.
*
* @param type the type that'll be used to create a mock instance
* @param methodName the name of the method to mock
* @param methodParameterTypes parameter types that define the method
* @param constructorArguments the constructor arguments
* @return a mock object of type T
*/
public static <T> T createPartialMock(Class<T> type, String methodName, Class<?>[] methodParameterTypes,
Object... constructorArguments);@Test
public void testOverloadedMethodPartialMocking() {
// Mock specific overloaded method: processData(String, boolean)
DataProcessor processor = PowerMock.createPartialMock(
DataProcessor.class, "processData", String.class, boolean.class);
expect(processor.processData("test data", true)).andReturn("processed with validation");
PowerMock.replay(processor);
// This call uses the mocked version: processData(String, boolean)
String result1 = processor.processData("test data", true);
// This call uses real implementation: processData(String)
String result2 = processor.processData("test data");
// This call uses real implementation: processData(byte[])
String result3 = processor.processData("test data".getBytes());
assertEquals("processed with validation", result1);
assertNotNull(result2); // Real implementation result
assertNotNull(result3); // Real implementation result
PowerMock.verify(processor);
}Mock methods at specific levels in the class inheritance hierarchy.
/**
* Mock methods at a specific place in the class hierarchy.
*
* @param type the type that'll be used to create a mock instance
* @param where where in the class hierarchy the methods reside
* @param methodNames the names of the methods that should be mocked
* @return a mock object of type T
*/
public static synchronized <T> T createPartialMock(Class<T> type, Class<? super T> where, String... methodNames);
/**
* Strictly mock methods at a specific place in the class hierarchy.
*
* @param type the type that'll be used to create a mock instance
* @param where where in the class hierarchy the methods reside
* @param methodNames the names of the methods that should be mocked
* @return a mock object of type T
*/
public static synchronized <T> T createStrictPartialMock(Class<T> type, Class<? super T> where, String... methodNames);
/**
* Nicely mock methods at a specific place in the class hierarchy.
*
* @param type the type that'll be used to create a mock instance
* @param where where in the class hierarchy the methods reside
* @param methodNames the names of the methods that should be mocked
* @return a mock object of type T
*/
public static synchronized <T> T createNicePartialMock(Class<T> type, Class<? super T> where, String... methodNames);class BaseValidator {
protected boolean validateFormat(String input) {
return input != null && input.length() > 0;
}
protected String formatError(String message) {
return "Error: " + message;
}
}
class EmailValidator extends BaseValidator {
@Override
protected boolean validateFormat(String email) {
return email.contains("@");
}
public ValidationResult validate(String email) {
// Uses validateFormat and formatError methods
if (validateFormat(email)) {
return ValidationResult.success();
} else {
return ValidationResult.failure(formatError("Invalid email format"));
}
}
}
@Test
public void testHierarchyPartialMocking() {
// Mock only the base class method, not the overridden one
EmailValidator validator = PowerMock.createPartialMock(
EmailValidator.class, BaseValidator.class, "formatError");
expect(validator.formatError("Invalid email format")).andReturn("Custom error message");
PowerMock.replay(validator);
// This uses the real overridden validateFormat method in EmailValidator
// But uses the mocked formatError method from BaseValidator
ValidationResult result = validator.validate("invalid-email");
assertFalse(result.isValid());
assertEquals("Custom error message", result.getErrorMessage());
PowerMock.verify(validator);
}@Test
public void testCombinedPartialMocking() throws Exception {
// Create partial mock with constructor, excluding some methods
String[] excludedMethods = {"calculateTotal", "formatOutput"};
OrderProcessor processor = PowerMock.createPartialMockForAllMethodsExcept(
OrderProcessor.class, excludedMethods);
// Mock the methods that aren't excluded
expect(processor.validateOrder(anyObject(Order.class))).andReturn(true);
expect(processor.applyDiscounts(anyObject(Order.class))).andReturn(new BigDecimal("10.00"));
processor.logProcessing(anyObject(Order.class));
PowerMock.expectLastCall();
PowerMock.replay(processor);
Order order = new Order("item1", new BigDecimal("100.00"));
// This uses mocked methods and real calculateTotal/formatOutput
String result = processor.processOrder(order);
assertNotNull(result);
assertTrue(result.contains("90.00")); // Real calculateTotal: 100 - 10 = 90
PowerMock.verify(processor);
}@Test
public void testProtectedMethodPartialMocking() {
DatabaseService dbService = PowerMock.createPartialMock(DatabaseService.class, "executeQuery");
// Mock protected method
expect(dbService.executeQuery("SELECT * FROM users")).andReturn("query result");
PowerMock.replay(dbService);
// Public method calls protected executeQuery internally
String result = dbService.getUsers();
assertEquals("processed: query result", result);
PowerMock.verify(dbService);
}PowerMock matches methods by name, so all overloaded methods with the same name will be mocked unless you specify parameter types explicitly.
Partial mocking works with final methods, which is not possible with standard mocking frameworks:
final class FinalService {
public final String processData(String data) {
return data.toUpperCase();
}
public final void logData(String data) {
System.out.println("Logging: " + data);
}
}
// This works with PowerMock
FinalService service = PowerMock.createPartialMock(FinalService.class, "logData");Partial mocks can be used alongside full mocks in the same test, providing flexibility in testing complex object interactions.
Install with Tessl CLI
npx tessl i tessl/maven-org-powermock--powermock-api-easymock