Using PowerMock with JUnit and Mockito

PowerMock is an open-source mocking library for Java applications. It extends the existing mocking frameworks, such as EasyMock and Mockito, to add even more powerful features to them. PowerMock enables us to write good unit tests for even the most untestable code. For example, most of the mocking frameworks in Java cannot mock static methods or final classes. But using PowerMock, we can mock almost any class.

PowerMock currently extends the EasyMock and Mockito mocking frameworks. Depending on which extension is preferred, the syntax to write any unit test differs slightly. In this tutorial, we are using PowerMock with Mockito.

This powermock tutorial will demonstrate a very simple mocking example using basic syntax for creating a mock and verifying a method invocation.

The primary usage of PowerMock has been the ability to mock static, final and/or private methods. Mockito2 now supports the mocking of final classes/methods. If you use Mockito2, it is recommended to use Mockito for mocking final methods/classes.

1. PowerMock Dependencies

To include powermock in our application, add the powermock-api-mockito2 and powermock-module-junit4 dependencies. Note that there is no official extension for JUnit 5.

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.12.4</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-core</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>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>2.0.9</version>
    <scope>test</scope>
</dependency>

If you plan to use its reflection module, for example invoking the private methods, then we need to import powermock-reflect module as well.

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-reflect</artifactId>
    <version>2.0.9</version>
    <scope>test</scope>
</dependency>

It is important to include the compatible versions of Mockito and PowerMock to avoid any possible runtime issues.

2. System Under Test

We are creating a simple class that has one private method, one final method and one static method. To eliminate unnecessary complexity, we are simply returning a String value from these methods. We will be mocking and testing these methods.

public class Service {
  private String privateMessage() {
    return "Hello World!";
  }

  public static String staticMessage() {
    return "Hello World!";
  }

  public final String finalMessage() {
    return "Hello World!";
  }
}

3. Preparing PowerMockito Extension

PowerMockito is a PowerMock’s extension API to support Mockito. PowerMockito uses Java Reflection API mock final, static or private methods to help Mockito to run tests using these methods.

To prepare for tests, we apply two annotations at the test class level. Here Service class contains the methods to be mocked.

@RunWith(PowerMockRunner.class)
@PrepareForTest( { Service.class })
public class AppTest {
...
}

In @PrepareForTest annotation, we can pass the fully qualified names of types we want to mock. For example, in the given declaration, PowerMockito will prepare all classes within the specified package for mocking.

@PrepareForTest(fullyQualifiedNames = "com.howtodoinjava.demo.service.*")

4. Mocking a Static Method

For mocking static methods, PowerMock provides two approaches:

  • Use PowerMockito.mockStatic() to a mock a static class or all the static methods in a class.
  • Use PowerMockito.spy() to mock a specific static method.
PowerMockito.mockStatic(Static.class);
Mockito.when(Static.staticMethod(paramIfAny)).thenReturn(value);

//or

Static spy = PowerMockito.spy(new Static());
PowerMockito.when(spy.staticMethod(paramIfAny)).thenReturn(value);

For the demo, we will mock the Service.staticMessage() method which is a static method in the Service class.

@Test
public void mockStaticMethodTest() {
  //Mock static methods
  PowerMockito.mockStatic(Service.class);

  //Set expectation
  Mockito.when(Service.staticMessage()).thenReturn("New Message from Mock!");

  //invoke the method
  String message = Service.staticMessage();

  //Assert the stub response
  Assert.assertEquals(message, "New Message from Mock!");
}

To verify the static method invocation, first, call PowerMockito.verifyStatic(Static.class) to start verifying behavior and then call the actual static method to verify. This is important to note that we need to call verifyStatic() per static method verification.

PowerMockito.verifyStatic(Service.class);
Service.staticMessage();

To verify the number of times the method is invoked, we can pass the Mockito.VerificationMode to the verifyStatic() method.

PowerMockito.verifyStatic(Service.class, Mockito.times(1));
Service.staticMessage();

5. Mocking a Final Method

The mocking of final methods is similar to static methods, except we need to use PowerMockito.mock(class) in place of mockStatic() method.

  @Test
  public void mockFinalMethodTest() {
    //Mock final method
    Service serviceMock = PowerMockito.mock(Service.class);

    //Set expectation
    Mockito.when(serviceMock.finalMessage()).thenReturn("New Message from Mock!");

    //invoke the method
    String message = serviceMock.finalMessage();

    //Assert the stub response
    Assert.assertEquals(message, "New Message from Mock!");
  }

To verify the final method invocations, we can use Mockito.verify() method.

    //Verify final method invocation
    Mockito.verify(serviceMock).finalMessage();

6. Mock a Private Method

For mocking the private methods, we will use the partial mocking using the spy() method. Also, we are using WhiteBox API to execute a private method in the class.

  @Test
  public void mockPrivateMethodTest() throws Exception {

    Service mock = PowerMockito.spy(new Service());
    PowerMockito.doReturn("New Message from Mock!").when(mock,"privateMessage");

    String privateMessage = Whitebox.invokeMethod(mock, "privateMessage");
    
    Assert.assertEquals(privateMessage, "New Message from Mock!");
  }

Use PowerMockito.verifyPrivate() method to verify the private method invocations.

PowerMockito.verifyPrivate(mock, times(1)).invoke("privateMessage");

7. Enable Verbose Logging

These mock settings are rarely used but can be useful in some cases. Use them if you want to name the mocks for future debugging purposes, or if you want to enable verbose logging for extra information.

@Test
  public void mockFinalMethodTest() {
    //Mock final method
    Service serviceMock = PowerMockito.mock(Service.class, Mockito
        .withSettings()
        .name("ServiceMock")
        .verboseLogging());

    //Set expectation
    Mockito.when(serviceMock.finalMessage()).thenReturn("New Message from Mock!");

    //invoke the method
    String message = serviceMock.finalMessage();

    //Assert the stub response
    Assert.assertEquals(message, "New Message from Mock!");

    //Verify final method invocation
    Mockito.verify(serviceMock).finalMessage();
  }

Run the above test to get the below result in the console. The finalMessage() has been referred in 3 places in the test:

  • While setting the expectation, it returns null.
  • When invoked on mock, it returns the stubbed response.
  • While verifying it returns null.
############ Logging method invocation #1 on mock/spy ########
ServiceMock.finalMessage();
   invoked: -> at com.howtodoinjava.demo.powermock.PowerMockTests.mockFinalMethodTest(PowerMockTests.java:46)
   has returned: "null"

############ Logging method invocation #2 on mock/spy ########
   stubbed: -> at com.howtodoinjava.demo.powermock.PowerMockTests.mockFinalMethodTest(PowerMockTests.java:46)
ServiceMock.finalMessage();
   invoked: -> at com.howtodoinjava.demo.powermock.PowerMockTests.mockFinalMethodTest(PowerMockTests.java:50)
   has returned: "New Message from Mock!" (java.lang.String)

############ Logging method invocation #3 on mock/spy ########
ServiceMock.finalMessage();
   invoked: -> at com.howtodoinjava.demo.powermock.PowerMockTests.mockFinalMethodTest(PowerMockTests.java:56)
   has returned: "null"

8. Conclusion

In this powermock tutorial, we learned to setup the powermock with mockito and JUnit. we learned to mock and stub private, static and final methods in a class under test. Finally, we learned to verify the method invocations and the count of invocations including verbose logging.

Happy Learning !!

Sourcecode on Github

Comments

Subscribe
Notify of
guest
4 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode