CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-powermock--powermock-api-easymock

PowerMock API extension for EasyMock providing advanced mocking capabilities for static methods, constructors, final classes, and private methods through bytecode manipulation.

Pending
Overview
Eval results
Files

partial-mocking.mddocs/

Partial Mocking

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.

Capabilities

Basic Partial Mocking by Method Names

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);

Usage Example

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);
    }
}

Inverse Partial Mocking (Mock All Except)

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);

Usage Example

@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);
}

Partial Mocking with Constructor Arguments

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);

Usage Example

@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);
}

Default Constructor Invocation

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;

Usage Example

@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);
}

Overloaded Method Partial Mocking

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);

Usage Example

@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);
}

Class Hierarchy Partial Mocking

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);

Usage Example

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);
}

Advanced Partial Mocking Patterns

Combining Multiple Partial Mocking Strategies

@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);
}

Testing Protected Methods

@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);
}

Important Notes

Method Name Matching

PowerMock matches methods by name, so all overloaded methods with the same name will be mocked unless you specify parameter types explicitly.

Final Method Support

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");

Integration with Full Mocks

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

docs

annotations.md

constructor-mocking.md

core-mocking.md

index.md

mock-control.md

partial-mocking.md

private-methods.md

reflection.md

static-mocking.md

tile.json