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

private-methods.mddocs/

Private Method Testing

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.

Capabilities

Basic Private Method Expectations

Set up expectations for private method calls using method names and arguments.

/**
 * Used to specify expectations on private methods using the method name.
 * 
 * @param instance the object instance containing the private method
 * @param methodName the name of the private method
 * @param arguments the method arguments
 * @return expectation setter for further configuration
 * @throws Exception if method cannot be found or invoked
 */
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, String methodName, Object... arguments) throws Exception;

/**
 * Used to specify expectations on private methods without specifying a method name.
 * PowerMock tries to find a unique method based on argument parameters.
 * 
 * @param instance the object instance containing the private method
 * @param arguments the method arguments
 * @return expectation setter for further configuration
 * @throws Exception if method cannot be found or invoked
 */
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, Object... arguments) throws Exception;

Usage Example

import org.powermock.api.easymock.PowerMock;
import org.powermock.reflect.Whitebox;

public class PrivateMethodTest {
    
    @Test
    public void testPrivateMethodExpectation() throws Exception {
        UserService userService = PowerMock.createPartialMock(UserService.class, "validateUser");
        
        // Set up expectation for private method call
        PowerMock.expectPrivate(userService, "validateUser", "john.doe")
                .andReturn(true);
        
        PowerMock.replay(userService);
        
        // Call public method that internally calls private validateUser method
        boolean result = userService.authenticateUser("john.doe", "password123");
        
        assertTrue(result);
        PowerMock.verify(userService);
    }
    
    @Test
    public void testPrivateMethodWithoutName() throws Exception {
        Calculator calculator = PowerMock.createPartialMock(Calculator.class, "computeInternal");
        
        // PowerMock finds method based on argument types
        PowerMock.expectPrivate(calculator, 5, 3)  // Finds method with (int, int) signature
                .andReturn(8);
        
        PowerMock.replay(calculator);
        
        int result = calculator.add(5, 3);  // Calls private computeInternal(5, 3)
        
        assertEquals(8, result);
        PowerMock.verify(calculator);
    }
}

Method Object-Based Expectations

Set up expectations using Method objects for precise method identification.

/**
 * Used to specify expectations on private methods using Method objects.
 * 
 * @param instance the object instance containing the private method
 * @param method the Method object representing the private method
 * @param arguments the method arguments
 * @return expectation setter for further configuration
 * @throws Exception if method cannot be invoked
 */
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, Method method, Object... arguments) throws Exception;

/**
 * Used to specify expectations on private static methods using Method objects.
 * 
 * @param clazz the class containing the private static method
 * @param method the Method object representing the private static method
 * @param arguments the method arguments
 * @return expectation setter for further configuration
 * @throws Exception if method cannot be invoked
 */
public static synchronized <T> IExpectationSetters<T> expectPrivate(Class<?> clazz, Method method, Object... arguments) throws Exception;

Usage Example

@Test
public void testPrivateMethodWithMethodObject() throws Exception {
    SecurityManager securityManager = PowerMock.createPartialMock(SecurityManager.class, "checkPermissions");
    
    // Get the private method using reflection
    Method checkPermissionsMethod = Whitebox.getMethod(SecurityManager.class, "checkPermissions", String.class, User.class);
    
    User testUser = new User("testuser");
    PowerMock.expectPrivate(securityManager, checkPermissionsMethod, "read", testUser)
            .andReturn(true);
    
    PowerMock.replay(securityManager);
    
    boolean hasAccess = securityManager.hasReadAccess("read", testUser);
    
    assertTrue(hasAccess);
    PowerMock.verify(securityManager);
}

Overloaded Private Method Expectations

Handle overloaded private methods by specifying parameter types explicitly.

/**
 * Used to specify expectations on overloaded private methods.
 * 
 * @param instance the object instance containing the private method
 * @param methodName the name of the private method
 * @param parameterTypes the parameter types to distinguish overloaded methods
 * @param arguments the method arguments
 * @return expectation setter for further configuration
 * @throws Exception if method cannot be found or invoked
 */
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, String methodName, 
                                                                   Class<?>[] parameterTypes, Object... arguments) throws Exception;

Usage Example

@Test
public void testOverloadedPrivateMethods() throws Exception {
    DataProcessor processor = PowerMock.createPartialMock(DataProcessor.class, "processData");
    
    // Handle overloaded private methods by specifying parameter types
    Class<?>[] stringArrayType = {String[].class};
    Class<?>[] listType = {List.class};
    
    String[] stringData = {"a", "b", "c"};
    List<String> listData = Arrays.asList("x", "y", "z");
    
    // Set up expectations for different overloaded methods
    PowerMock.expectPrivate(processor, "processData", stringArrayType, new Object[]{stringData})
            .andReturn("array-processed");
    
    PowerMock.expectPrivate(processor, "processData", listType, listData)
            .andReturn("list-processed");
    
    PowerMock.replay(processor);
    
    String result1 = processor.handleArrayData(stringData);  // Calls processData(String[])
    String result2 = processor.handleListData(listData);     // Calls processData(List)
    
    assertEquals("array-processed", result1);
    assertEquals("list-processed", result2);
    PowerMock.verify(processor);
}

Class Hierarchy Private Method Expectations

Specify private method expectations at specific levels in the class hierarchy.

/**
 * Used to specify expectations for private methods at a specific place in the class hierarchy.
 * 
 * @param instance the object instance containing the private method
 * @param methodName the name of the private method
 * @param where the class in the hierarchy where the method is defined
 * @param arguments the method arguments
 * @return expectation setter for further configuration
 * @throws Exception if method cannot be found or invoked
 */
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, String methodName, 
                                                                   Class<?> where, Object... arguments) throws Exception;

/**
 * Used to specify expectations for overloaded private methods at a specific place in the class hierarchy.
 * 
 * @param instance the object instance containing the private method
 * @param methodName the name of the private method
 * @param where the class in the hierarchy where the method is defined
 * @param parameterTypes the parameter types to distinguish overloaded methods
 * @param arguments the method arguments
 * @return expectation setter for further configuration
 * @throws Exception if method cannot be found or invoked
 */
public static synchronized <T> IExpectationSetters<T> expectPrivate(Object instance, String methodName, 
                                                                   Class<?> where, Class<?>[] parameterTypes, Object... arguments) throws Exception;

Usage Example

class BaseService {
    private String formatMessage(String msg) {
        return "Base: " + msg;
    }
}

class ExtendedService extends BaseService {
    private String formatMessage(String msg) {
        return "Extended: " + msg;
    }
    
    public String processMessage(String msg) {
        // Calls private method - but which one?
        return formatMessage(msg);
    }
}

@Test
public void testPrivateMethodInHierarchy() throws Exception {
    ExtendedService service = PowerMock.createPartialMock(ExtendedService.class, "formatMessage");
    
    // Specify which class's private method to mock
    PowerMock.expectPrivate(service, "formatMessage", BaseService.class, "test")
            .andReturn("Mocked base message");
    
    PowerMock.expectPrivate(service, "formatMessage", ExtendedService.class, "test")
            .andReturn("Mocked extended message");
    
    PowerMock.replay(service);
    
    String result = service.processMessage("test");
    
    assertEquals("Mocked extended message", result);  // Uses ExtendedService's method
    PowerMock.verify(service);
}

Advanced Private Method Testing

Testing Private Method Side Effects

Verify that private methods are called with expected parameters and frequencies.

@Test
public void testPrivateMethodSideEffects() throws Exception {
    AuditLogger logger = PowerMock.createPartialMock(AuditLogger.class, "writeToFile");
    
    // Expect private method to be called twice with different parameters
    PowerMock.expectPrivate(logger, "writeToFile", "login", "user1").once();
    PowerMock.expectPrivate(logger, "writeToFile", "logout", "user1").once();
    
    PowerMock.replay(logger);
    
    // Public methods that internally call private writeToFile method
    logger.logUserLogin("user1");
    logger.logUserLogout("user1");
    
    PowerMock.verify(logger);  // Verifies both private method calls occurred
}

Exception Handling in Private Methods

Set up private method expectations to throw exceptions.

@Test(expected = ProcessingException.class)
public void testPrivateMethodThrowsException() throws Exception {
    FileManager fileManager = PowerMock.createPartialMock(FileManager.class, "validatePath");
    
    PowerMock.expectPrivate(fileManager, "validatePath", "/invalid/path")
            .andThrow(new ProcessingException("Invalid path"));
    
    PowerMock.replay(fileManager);
    
    fileManager.openFile("/invalid/path");  // Calls private validatePath method
    
    // Test expects ProcessingException to be thrown
}

Integration with Whitebox Testing

Combine private method expectations with direct private method invocation testing.

@Test
public void testPrivateMethodDirectly() throws Exception {
    CryptoService cryptoService = new CryptoService();
    
    // Test private method directly using Whitebox
    String result = Whitebox.invokeMethod(cryptoService, "generateSalt", 16);
    assertNotNull(result);
    assertEquals(16, result.length());
    
    // Also test through partial mocking
    CryptoService mockCrypto = PowerMock.createPartialMock(CryptoService.class, "generateSalt");
    PowerMock.expectPrivate(mockCrypto, "generateSalt", 16).andReturn("fixed-salt-value");
    PowerMock.replay(mockCrypto);
    
    String encryptedData = mockCrypto.encryptData("secret");  // Uses mocked generateSalt
    assertTrue(encryptedData.contains("fixed-salt-value"));
    
    PowerMock.verify(mockCrypto);
}

Important Notes

Partial Mocking Requirement

To set up expectations for private methods, you must create a partial mock that includes the private method names:

// Correct: Include private method in partial mock
MyService service = PowerMock.createPartialMock(MyService.class, "privateMethod");

// Incorrect: Full mock doesn't allow private method expectations
MyService service = PowerMock.createMock(MyService.class);  // Won't work for private methods

Method Visibility

PowerMock can access private methods from any visibility level:

  • private - Standard private methods
  • protected - Protected methods accessible in subclasses
  • Package-private - Methods with no access modifier

Static Private Methods

Private static methods are handled similarly but use the class instead of instance:

PowerMock.expectPrivate(MyUtilClass.class, "privateStaticMethod", "param")
        .andReturn("result");

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