PowerMock and Mockito: Comprehensive Guide to Java Unit Testing and Mocking Techniques
This comprehensive guide walks Java developers through setting up PowerMock and Mockito, demonstrates creating and spying on mocks, stubbing methods, using parameter matchers, verifying interactions—including static and private members—and explains essential annotations and best‑practice principles for robust, maintainable unit tests.
In this tutorial we explore how to write effective Java unit tests using PowerMock and Mockito. The guide follows the principle "simplify complex problems, deepen simple problems" and shows how to break down complex logic into simple, testable units.
1. Environment Preparation
PowerMock extends other mock frameworks (such as EasyMock) and can mock static methods, constructors, final classes, private methods, and more. To use PowerMock you need to add the following Maven dependencies to pom.xml :
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>For Spring MVC or Spring Boot projects you also need the JUnit dependency:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>2. Basic Mock Example
public class ListTest {
@Test
public void testSize() {
Integer expected = 100;
List list = PowerMockito.mock(List.class);
PowerMockito.when(list.size()).thenReturn(expected);
Integer actual = list.size();
Assert.assertEquals("返回值不相等", expected, actual);
}
}3. Mock Statements
mock() creates a mock instance of a class. PowerMockito.mockStatic(Class) mocks static methods, and PowerMockito.spy(Class) creates a partial mock (spy) that calls real methods unless stubbed.
PowerMockito.mockStatic(StringUtils.class);
PowerMockito.spy(StringUtils.class);4. Stubbing with when().thenReturn()
PowerMockito.when(mockList.get(index)).thenReturn(expected);Other stubbing options include thenThrow , thenAnswer , and thenCallRealMethod .
5. Stubbing with doReturn().when()
PowerMockito.doReturn(expected).when(mockObject).someMethod(args);This form does not invoke the original method, which is useful when stubbing spies.
6. Parameter Matchers
Mockito provides matchers such as anyInt() , anyString() , and eq() to ignore or verify specific arguments.
PowerMockito.when(mockList.get(Mockito.anyInt())).thenReturn(expected);
PowerMockito.when(StringUtils.startsWith(Mockito.anyString(), Mockito.eq(prefix))).thenReturn(true);AdditionalMatchers offers gt , lt , geq , leq , and , or , etc.
7. Verification
Use Mockito.verify() to ensure that a method was called, optionally specifying the number of invocations.
Mockito.verify(mockList).clear();
Mockito.verify(mockList, Mockito.times(1)).clear();In‑order verification can be performed with InOrder :
InOrder inOrder = Mockito.inOrder(mockedList);
inOrder.verify(mockedList).add(1);
inOrder.verify(mockedList).add(2);Argument captors capture the actual arguments passed to a mock:
ArgumentCaptor
captor = ArgumentCaptor.forClass(Integer.class);
Mockito.verify(mockedList, Mockito.times(3)).add(captor.capture());
Integer[] actuals = captor.getAllValues().toArray(new Integer[0]);8. Verifying No More Interactions
Mockito.verifyNoMoreInteractions(mockedList);9. Verifying Static Methods
PowerMockito.mockStatic(StringUtils.class);
StringUtils.isEmpty("abc");
PowerMockito.verifyStatic(StringUtils.class);
StringUtils.isEmpty(Mockito.anyString());10. Private Fields and Methods
Use ReflectionTestUtils.setField (Spring) or Whitebox.setInternalState (PowerMock) to set private fields.
ReflectionTestUtils.setField(userService, "userLimit", 1000L);
Whitebox.setInternalState(userService, "userLimit", 1000L);Private methods can be stubbed with PowerMockito.when(object, "methodName", args...).thenReturn(value) or verified with PowerMockito.verifyPrivate(object).invoke("methodName", args...) .
UserService service = PowerMockito.spy(new UserService());
PowerMockito.when(service, "isSuperUser", userId).thenReturn(true);
boolean result = service.isNotSuperUser(userId);
PowerMockito.verifyPrivate(service).invoke("isSuperUser", userId);11. Important Annotations
@RunWith(PowerMockRunner.class) – use PowerMock’s test runner.
@PrepareForTest({TargetClass.class}) – required for mocking final/static methods.
@Mock – creates a fully mocked instance.
@Spy – creates a partial mock (real methods unless stubbed).
@InjectMocks – creates an instance and injects mocks/spies into it.
@Captor – creates an ArgumentCaptor (must call MockitoAnnotations.openMocks(this) ).
@PowerMockIgnore – avoids class‑loader issues with certain packages.
12. Best Practices and Viewpoints
The guide also presents the AIR principles (Automatic, Independent, Repeatable) and the BCDE testing principles (Border, Correct, Design, Error) for writing high‑quality unit tests.
Overall, the article provides a complete reference for using PowerMock and Mockito to write robust Java unit tests, covering mock creation, stubbing, parameter matching, verification, private member handling, and essential annotations.
Amap Tech
Official Amap technology account showcasing all of Amap's technical innovations.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.