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

mock-control.mddocs/

Mock Control and Lifecycle

PowerMock provides comprehensive control over mock behavior through replay/verify cycles and state management. These capabilities enable sophisticated testing scenarios with multiple mocks, bulk operations, and integration with EasyMock's control mechanisms.

Capabilities

Bulk Mock Operations

Control all PowerMock-managed mocks with single method calls.

/**
 * Replay all classes and mock objects known by PowerMock.
 * 
 * @param additionalMocks mocks not created by PowerMock API to include in replay
 */
public static synchronized void replayAll(Object... additionalMocks);

/**
 * Verify all classes and mock objects known by PowerMock.
 */
public static synchronized void verifyAll();

/**
 * Reset all classes and mock objects known by PowerMock.
 * 
 * @param additionalMocks mocks not created by PowerMock API to include in reset
 */
public static synchronized void resetAll(Object... additionalMocks);

Usage Example

import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;

@PrepareForTest({FileUtils.class, DatabaseService.class})
public class BulkMockControlTest {
    
    @Test
    public void testBulkMockOperations() throws Exception {
        // Create various types of mocks
        UserService userService = PowerMock.createMock(UserService.class);
        PowerMock.mockStatic(FileUtils.class);
        PowerMock.expectNew(DatabaseService.class, "localhost").andReturn(mockDbService);
        
        // Set up expectations for all mocks
        expect(userService.getUserById(1)).andReturn(new User("john"));
        expect(FileUtils.readFile("config.txt")).andReturn("config data");
        expect(mockDbService.connect()).andReturn(true);
        
        // Replay all mocks at once
        PowerMock.replayAll();
        
        // Test your code that uses all these mocks
        ApplicationService appService = new ApplicationService();
        String result = appService.processUser(1);
        
        assertEquals("Processed user john with config data", result);
        
        // Verify all mocks at once
        PowerMock.verifyAll();
    }
}

Individual Mock Control

Control specific mock objects and classes individually.

/**
 * Switches mocks or classes to replay mode.
 * 
 * @param mocks mock objects or classes loaded by PowerMock
 * @throws RuntimeException if something unexpected goes wrong
 */
public static synchronized void replay(Object... mocks);

/**
 * Switches mocks or classes to verify mode.
 * 
 * @param objects mock objects or classes loaded by PowerMock
 */
public static synchronized void verify(Object... objects);

/**
 * Reset a list of mock objects or classes.
 * 
 * @param mocks mock objects or classes to reset
 */
public static synchronized void reset(Object... mocks);

Usage Example

@Test
public void testIndividualMockControl() {
    UserService userService = PowerMock.createMock(UserService.class);
    OrderService orderService = PowerMock.createMock(OrderService.class);
    
    // Set up expectations
    expect(userService.getUserById(1)).andReturn(new User("alice"));
    expect(orderService.getOrdersByUser(1)).andReturn(Arrays.asList(new Order("order1")));
    
    // Replay specific mocks
    PowerMock.replay(userService, orderService);
    
    // Test code
    User user = userService.getUserById(1);
    List<Order> orders = orderService.getOrdersByUser(1);
    
    assertEquals("alice", user.getName());
    assertEquals(1, orders.size());
    
    // Verify specific mocks
    PowerMock.verify(userService, orderService);
}

EasyMock Integration

Use standard EasyMock expectation methods with PowerMock-created mocks.

/**
 * This method delegates to EasyMock's expectLastCall() method.
 * 
 * @return the expectation setter
 */
public static synchronized IExpectationSetters<Object> expectLastCall();

Usage Example

@Test
public void testEasyMockIntegration() {
    Logger logger = PowerMock.createMock(Logger.class);
    
    // Void method expectation using expectLastCall
    logger.info("Starting process");
    PowerMock.expectLastCall().times(2);  // Expect this call twice
    
    logger.error("Process failed");
    PowerMock.expectLastCall().andThrow(new RuntimeException("Logging system down"));
    
    PowerMock.replay(logger);
    
    // First two calls succeed
    logger.info("Starting process");
    logger.info("Starting process");
    
    // Third call throws exception
    try {
        logger.error("Process failed");
        fail("Expected exception");
    } catch (RuntimeException e) {
        assertEquals("Logging system down", e.getMessage());
    }
    
    PowerMock.verify(logger);
}

Nice Replay and Verify Mode

Enable lenient mode for tests that use both mocks and non-mock objects.

/**
 * Sometimes it is useful to allow replay and verify on non-mocks.
 * For example when using partial mocking in some tests and no mocking in other test methods.
 */
public static synchronized void niceReplayAndVerify();

Usage Example

@Test
public void testNiceReplayAndVerify() {
    // Enable nice mode for mixed mock/non-mock scenarios
    PowerMock.niceReplayAndVerify();
    
    UserService mockUserService = PowerMock.createMock(UserService.class);
    OrderService realOrderService = new OrderService(); // Real object, not a mock
    
    expect(mockUserService.getUserById(1)).andReturn(new User("bob"));
    
    PowerMock.replayAll();
    
    // Test code that uses both mocks and real objects
    User user = mockUserService.getUserById(1);
    List<Order> orders = realOrderService.getOrdersByUser(1); // Real method call
    
    // verifyAll() won't fail on the real object in nice mode
    PowerMock.verifyAll();
}

Advanced Mock Control Patterns

Sequential Mock State Management

Control mock states through multiple test phases.

@Test
public void testSequentialMockStates() {
    DatabaseConnection connection = PowerMock.createMock(DatabaseConnection.class);
    
    // Phase 1: Initial expectations
    expect(connection.connect()).andReturn(true);
    expect(connection.executeQuery("SELECT 1")).andReturn("1");
    PowerMock.replay(connection);
    
    // Execute phase 1
    assertTrue(connection.connect());
    assertEquals("1", connection.executeQuery("SELECT 1"));
    PowerMock.verify(connection);
    
    // Reset for phase 2
    PowerMock.reset(connection);
    expect(connection.executeQuery("SELECT 2")).andReturn("2");
    expect(connection.disconnect()).andReturn(true);
    PowerMock.replay(connection);
    
    // Execute phase 2
    assertEquals("2", connection.executeQuery("SELECT 2"));
    assertTrue(connection.disconnect());
    PowerMock.verify(connection);
}

Mixed Mock Types Control

Manage different types of mocks (instance, static, constructor) together.

@PrepareForTest({FileUtils.class, MyService.class})
@Test
public void testMixedMockTypes() throws Exception {
    // Instance mock
    Logger logger = PowerMock.createMock(Logger.class);
    
    // Static mock
    PowerMock.mockStatic(FileUtils.class);
    
    // Constructor mock
    DatabaseConnection mockConnection = PowerMock.createMock(DatabaseConnection.class);
    PowerMock.expectNew(DatabaseConnection.class, "localhost").andReturn(mockConnection);
    
    // Set up all expectations
    logger.info("Processing started");
    PowerMock.expectLastCall();
    expect(FileUtils.readFile("input.txt")).andReturn("file content");
    expect(mockConnection.isConnected()).andReturn(true);
    
    // Control all mocks together
    PowerMock.replayAll();
    
    // Test code using all mock types
    MyService service = new MyService(logger);
    String result = service.processFile("input.txt"); // Uses all three mock types
    
    assertEquals("Processed: file content", result);
    PowerMock.verifyAll();
}

Conditional Mock Control

Apply different control strategies based on test conditions.

@Test
public void testConditionalMockControl() {
    boolean useStrictMode = true;
    
    UserService userService;
    if (useStrictMode) {
        userService = PowerMock.createStrictMock(UserService.class);
        // Strict mode requires exact order
        expect(userService.validateUser("john")).andReturn(true);
        expect(userService.getUserDetails("john")).andReturn(new UserDetails("john", "admin"));
    } else {
        userService = PowerMock.createNiceMock(UserService.class);
        // Nice mode allows any order
        expect(userService.validateUser("john")).andReturn(true);
        expect(userService.getUserDetails("john")).andReturn(new UserDetails("john", "admin"));
    }
    
    PowerMock.replay(userService);
    
    // Test code - order matters in strict mode
    boolean valid = userService.validateUser("john");
    UserDetails details = userService.getUserDetails("john");
    
    assertTrue(valid);
    assertEquals("admin", details.getRole());
    
    PowerMock.verify(userService);
}

Exception Handling in Mock Control

Handle exceptions during mock control operations.

@Test
public void testMockControlExceptionHandling() {
    List<Object> mocks = new ArrayList<>();
    
    try {
        UserService userService = PowerMock.createMock(UserService.class);
        OrderService orderService = PowerMock.createMock(OrderService.class);
        mocks.addAll(Arrays.asList(userService, orderService));
        
        // Set up expectations that might fail
        expect(userService.getUserById(1)).andReturn(new User("test"));
        expect(orderService.getOrdersByUser(1)).andThrow(new ServiceException("Database error"));
        
        PowerMock.replay(userService, orderService);
        
        // Test code
        User user = userService.getUserById(1);
        try {
            orderService.getOrdersByUser(1);
            fail("Expected ServiceException");
        } catch (ServiceException e) {
            assertEquals("Database error", e.getMessage());
        }
        
        PowerMock.verify(userService, orderService);
        
    } catch (Exception e) {
        // Clean up mocks if test fails
        if (!mocks.isEmpty()) {
            PowerMock.reset(mocks.toArray());
        }
        throw e;
    }
}

Best Practices

Test Setup and Teardown

public class MockControlBestPracticesTest {
    private UserService userService;
    private OrderService orderService;
    
    @Before
    public void setUp() {
        userService = PowerMock.createMock(UserService.class);
        orderService = PowerMock.createMock(OrderService.class);
    }
    
    @After
    public void tearDown() {
        // Reset all mocks after each test
        PowerMock.resetAll();
    }
    
    @Test
    public void testWithCleanSetup() {
        // Test implementation - mocks are clean from setUp()
        expect(userService.getUserById(1)).andReturn(new User("clean"));
        PowerMock.replayAll();
        
        User user = userService.getUserById(1);
        assertEquals("clean", user.getName());
        
        PowerMock.verifyAll();
        // tearDown() will reset mocks automatically
    }
}

Verification Error Handling

@Test
public void testVerificationWithErrorHandling() {
    Calculator calculator = PowerMock.createStrictMock(Calculator.class);
    
    expect(calculator.add(5, 3)).andReturn(8);
    expect(calculator.multiply(8, 2)).andReturn(16);
    PowerMock.replay(calculator);
    
    // Perform operations
    int sum = calculator.add(5, 3);
    
    try {
        PowerMock.verify(calculator);
        fail("Should have failed - multiply not called");
    } catch (AssertionError e) {
        // Expected - multiply method was not called
        assertTrue(e.getMessage().contains("multiply"));
    }
    
    // Complete the expected interactions
    int product = calculator.multiply(8, 2);
    PowerMock.verify(calculator); // Now passes
}

Important Notes

Mock Lifecycle

  1. Create - Create mocks using PowerMock factory methods
  2. Setup - Configure expectations using expect() and expectLastCall()
  3. Replay - Switch to replay mode using replay() or replayAll()
  4. Execute - Run the code under test
  5. Verify - Check expectations using verify() or verifyAll()
  6. Reset - Clean up for next test using reset() or resetAll()

Thread Safety

Mock control operations are synchronized but the mocks themselves are not thread-safe. Avoid sharing mocks across concurrent test execution.

Integration with Test Frameworks

PowerMock mock control integrates seamlessly with JUnit, TestNG, and other testing frameworks through proper setup and teardown methods.

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