PowerMock API extension for EasyMock providing advanced mocking capabilities for static methods, constructors, final classes, and private methods through bytecode manipulation.
—
PowerMock provides annotation-based configuration that simplifies mock setup and reduces boilerplate code. This declarative approach improves test readability and maintainability while providing automatic mock lifecycle management.
Automatically create and inject mock objects using field annotations.
/**
* Annotation for automatic mock creation and injection.
* Can be placed on fields to eliminate manual mock setup.
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Mock {
/**
* Method names to mock for partial mocking.
* If empty, all methods are mocked.
*/
String[] value() default "";
/**
* Specific field name for targeted mock injection.
* When set, mock will be assigned to the given field name in test subjects.
*/
String fieldName() default "";
}import org.powermock.api.easymock.annotation.Mock;
import org.powermock.api.extension.listener.AnnotationEnabler;
import org.powermock.core.classloader.annotations.PowerMockListener;
@PowerMockListener(AnnotationEnabler.class)
public class BasicAnnotationTest {
@Mock
private UserService userService;
@Mock
private OrderService orderService;
private ShoppingCart shoppingCart;
@Before
public void setUp() {
shoppingCart = new ShoppingCart(userService, orderService);
}
@Test
public void testAnnotationBasedMocks() {
// Mocks are automatically created and available
expect(userService.getCurrentUser()).andReturn(new User("john"));
expect(orderService.getPendingOrders("john")).andReturn(Arrays.asList(new Order("order1")));
PowerMock.replayAll();
List<Order> orders = shoppingCart.getUserOrders();
assertEquals(1, orders.size());
assertEquals("order1", orders.get(0).getId());
PowerMock.verifyAll();
}
}Create strict mocks that verify method call order using annotations.
/**
* Annotation for automatic strict mock creation.
* Strict mocks check the order of method calls.
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MockStrict {
/**
* Method names to mock for partial mocking.
* If empty, all methods are mocked.
*/
String[] value() default "";
}@PowerMockListener(AnnotationEnabler.class)
public class StrictAnnotationTest {
@MockStrict
private DatabaseConnection connection;
@MockStrict
private Logger logger;
private DataProcessor processor;
@Before
public void setUp() {
processor = new DataProcessor(connection, logger);
}
@Test
public void testStrictMockAnnotations() {
// Strict mocks verify exact order of calls
expect(logger.info("Starting connection")).andReturn(true);
expect(connection.connect()).andReturn(true);
expect(connection.executeQuery("SELECT * FROM data")).andReturn("data");
expect(logger.info("Connection completed")).andReturn(true);
expect(connection.disconnect()).andReturn(true);
PowerMock.replayAll();
// These calls must happen in exactly this order
String result = processor.processData();
assertEquals("Processed: data", result);
PowerMock.verifyAll();
}
}Create nice mocks that provide default return values for unexpected calls.
/**
* Annotation for automatic nice mock creation.
* Nice mocks allow unexpected method calls and return appropriate default values.
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MockNice {
/**
* Method names to mock for partial mocking.
* If empty, all methods are mocked.
*/
String[] value() default "";
}@PowerMockListener(AnnotationEnabler.class)
public class NiceAnnotationTest {
@MockNice
private ConfigurationService configService;
@MockNice
private Logger logger;
private ApplicationService appService;
@Before
public void setUp() {
appService = new ApplicationService(configService, logger);
}
@Test
public void testNiceMockAnnotations() {
// Only set up the expectations you care about
expect(configService.getProperty("app.name")).andReturn("TestApp");
PowerMock.replayAll();
// This call has explicit expectation
String appName = appService.getApplicationName();
assertEquals("TestApp", appName);
// These calls don't have expectations but work with nice mocks
appService.logStartup(); // logger methods return void (default)
String version = appService.getVersion(); // Returns null (default for String)
PowerMock.verifyAll();
}
}Use annotations to create partial mocks that only mock specific methods.
@PowerMockListener(AnnotationEnabler.class)
public class PartialMockAnnotationTest {
// Only mock the sendEmail and logEmailSent methods
@Mock({"sendEmail", "logEmailSent"})
private EmailService emailService;
// Only mock the validateInput method
@MockStrict({"validateInput"})
private InputValidator validator;
@Test
public void testPartialMockingWithAnnotations() {
// Set up expectations for mocked methods only
expect(validator.validateInput("test input")).andReturn(true);
expect(emailService.sendEmail("test@example.com", "Subject", "Body")).andReturn(true);
emailService.logEmailSent("test@example.com");
PowerMock.expectLastCall();
PowerMock.replayAll();
// Mocked methods
boolean isValid = validator.validateInput("test input");
boolean sent = emailService.sendEmail("test@example.com", "Subject", "Body");
emailService.logEmailSent("test@example.com");
// Non-mocked methods use real implementation
String formatted = validator.formatInput("test input"); // Real behavior
String serverInfo = emailService.getServerInfo(); // Real behavior
assertTrue(isValid);
assertTrue(sent);
assertNotNull(formatted);
assertNotNull(serverInfo);
PowerMock.verifyAll();
}
}Use the fieldName attribute to control mock injection into specific fields.
public class TestSubject {
private UserService primaryUserService;
private UserService backupUserService;
private OrderService orderService;
}
@PowerMockListener(AnnotationEnabler.class)
public class FieldTargetingTest {
// Inject into primaryUserService field specifically
@Mock(fieldName = "primaryUserService")
private UserService mockPrimaryUserService;
// Inject into backupUserService field specifically
@Mock(fieldName = "backupUserService")
private UserService mockBackupUserService;
@Mock
private OrderService orderService;
@TestSubject
private TestSubject testSubject;
@Test
public void testFieldNameTargeting() {
// Set up different behaviors for different UserService instances
expect(mockPrimaryUserService.getUserById(1)).andReturn(new User("primary-user"));
expect(mockBackupUserService.getUserById(1)).andReturn(new User("backup-user"));
expect(orderService.getOrdersByUser(1)).andReturn(Arrays.asList(new Order("order1")));
PowerMock.replayAll();
// testSubject now has different mocks injected into specific fields
String result = testSubject.processUserWithBackup(1);
assertTrue(result.contains("primary-user"));
assertTrue(result.contains("backup-user"));
PowerMock.verifyAll();
}
}Mix different annotation types in the same test class for complex scenarios.
@PowerMockListener(AnnotationEnabler.class)
public class MixedAnnotationTest {
@Mock
private UserService userService; // Regular mock
@MockStrict
private DatabaseConnection connection; // Strict mock
@MockNice
private Logger logger; // Nice mock
@Mock({"validatePermissions"})
private SecurityService securityService; // Partial mock
@Test
public void testMixedAnnotationTypes() {
// Set up expectations based on mock types
expect(userService.getUserById(1)).andReturn(new User("test"));
// Strict mock - order matters
expect(connection.connect()).andReturn(true);
expect(connection.executeQuery(anyString())).andReturn("data");
expect(connection.disconnect()).andReturn(true);
// Partial mock - only mocked method needs expectation
expect(securityService.validatePermissions("test", "read")).andReturn(true);
// Nice mock - no explicit expectations needed
PowerMock.replayAll();
// Test code uses all mock types
MyService service = new MyService(userService, connection, logger, securityService);
String result = service.processUserData(1);
assertNotNull(result);
PowerMock.verifyAll();
}
}Combine annotations with programmatic static and constructor mocking.
@PowerMockListener(AnnotationEnabler.class)
@PrepareForTest({FileUtils.class, DatabaseConnection.class})
public class HybridAnnotationTest {
@Mock
private UserService userService;
@MockStrict
private Logger logger;
@Test
public void testAnnotationsWithStaticMocking() throws Exception {
// Annotation-based mocks
expect(userService.getUserById(1)).andReturn(new User("test"));
expect(logger.info("Processing user")).andReturn(true);
// Programmatic static mocking
PowerMock.mockStatic(FileUtils.class);
expect(FileUtils.readFile("config.txt")).andReturn("config data");
// Programmatic constructor mocking
DatabaseConnection mockConnection = PowerMock.createMock(DatabaseConnection.class);
PowerMock.expectNew(DatabaseConnection.class, "localhost").andReturn(mockConnection);
expect(mockConnection.connect()).andReturn(true);
PowerMock.replayAll();
// Test code using both annotation and programmatic mocks
HybridService service = new HybridService(userService, logger);
String result = service.processUserWithConfig(1);
assertNotNull(result);
PowerMock.verifyAll();
}
}Ensure proper annotation processing dependencies are available:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>Always include the @PowerMockListener(AnnotationEnabler.class) annotation:
@RunWith(PowerMockRunner.class) // If using JUnit 4
@PowerMockListener(AnnotationEnabler.class) // Required for annotation processing
@PrepareForTest({ClassesWithStaticMethods.class}) // If using static mocking
public class AnnotationConfiguredTest {
// Test implementation
}For TestNG, use the PowerMock TestNG listener:
@PowerMockListener(AnnotationEnabler.class)
public class TestNGAnnotationTest extends PowerMockTestCase {
@Mock
private UserService userService;
@Test
public void testWithTestNG() {
expect(userService.getUserById(1)).andReturn(new User("testng-user"));
PowerMock.replayAll();
// Test implementation
PowerMock.verifyAll();
}
}@PowerMockListener(AnnotationEnabler.class)
public class WellOrganizedAnnotationTest {
// Group related mocks together
// Core service mocks
@Mock private UserService userService;
@Mock private OrderService orderService;
// Infrastructure mocks
@MockStrict private DatabaseConnection connection;
@MockNice private Logger logger;
// Partial mocks for complex services
@Mock({"validate", "transform"})
private DataProcessor dataProcessor;
// Test subjects
@TestSubject
private ApplicationService applicationService;
@Test
public void testWellOrganized() {
// Clear test implementation
}
}@PowerMockListener(AnnotationEnabler.class)
public class MockLifecycleTest {
@Mock private UserService userService;
@MockStrict private AuditLogger auditLogger;
@Before
public void setUpMocks() {
// Additional setup after annotation processing
// Mocks are already created by annotations
}
@After
public void tearDownMocks() {
// PowerMock automatically handles cleanup
// Manual cleanup only if needed for special cases
PowerMock.resetAll();
}
@Test
public void testWithLifecycleManagement() {
// Test implementation
PowerMock.replayAll();
// Test execution
PowerMock.verifyAll();
}
}@Before) run after annotation processingAnnotations work well with dependency injection frameworks:
@PowerMockListener(AnnotationEnabler.class)
public class DIIntegrationTest {
@Mock private DatabaseService databaseService;
@Mock private EmailService emailService;
@TestSubject // Automatically injects mocks into this object
private UserRegistrationService registrationService;
@Test
public void testWithDependencyInjection() {
// Mocks are automatically injected into registrationService
expect(databaseService.saveUser(anyObject(User.class))).andReturn(true);
expect(emailService.sendWelcomeEmail(anyString())).andReturn(true);
PowerMock.replayAll();
boolean result = registrationService.registerUser("john@example.com", "password");
assertTrue(result);
PowerMock.verifyAll();
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-powermock--powermock-api-easymock