Tutorial

Mockito Mock Static Method - PowerMock

Published on August 3, 2022
author

Pankaj

Mockito Mock Static Method - PowerMock

Mockito allows us to create mock objects. Since static method belongs to the class, there is no way in Mockito to mock static methods. However, we can use PowerMock along with Mockito framework to mock static methods.

Mockito Mock Static Method using PowerMock

PowerMock provides different modules to extend Mockito framework and run JUnit and TestNG test cases. Note that PowerMock doesn’t support JUnit 5 yet, so we will create JUnit 4 test cases. We will also learn how to integrate TestNG with Mockito and PowerMock.

PowerMock Dependencies

We need following PowerMock dependencies for mocking static methods in Mockito.

  • powermock-api-mockito2: This is the core PowerMock dependency and used to extend Mockito2 mocking framework. If you are using Mockito 1.x versions then use powermock-api-mockito module.
  • powermock-module-junit4: For running JUnit 4 test cases using PowerMock.
  • powermock-module-testng: For running TestNG test cases and supporting PowerMock.

Below is the final pom.xml from our project.

<project xmlns="https://maven.apache.org/POM/4.0.0"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.journaldev.powermock</groupId>
	<artifactId>PowerMock-Examples</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<testng.version>6.14.3</testng.version>
		<junit4.version>4.12</junit4.version>
		<mockito-core.version>2.19.0</mockito-core.version>
		<powermock.version>2.0.0-beta.5</powermock.version>
		<java.version>10</java.version>
	</properties>

	<dependencies>
		<!-- TestNG -->
		<dependency>
			<groupId>org.testng</groupId>
			<artifactId>testng</artifactId>
			<version>${testng.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- JUnit 4 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit4.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- Mockito 2 -->
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<version>${mockito-core.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- PowerMock TestNG Module -->
		<dependency>
			<groupId>org.powermock</groupId>
			<artifactId>powermock-module-testng</artifactId>
			<version>${powermock.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- PowerMock JUnit 4.4+ Module -->
		<dependency>
			<groupId>org.powermock</groupId>
			<artifactId>powermock-module-junit4</artifactId>
			<version>${powermock.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- PowerMock Mockito2 API -->
		<dependency>
			<groupId>org.powermock</groupId>
			<artifactId>powermock-api-mockito2</artifactId>
			<version>${powermock.version}</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.7.0</version>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.22.0</version>
				<dependencies>
					<dependency>
						<groupId>org.apache.maven.surefire</groupId>
						<artifactId>surefire-junit47</artifactId>
						<version>2.22.0</version>
					</dependency>
					<dependency>
						<groupId>org.apache.maven.surefire</groupId>
						<artifactId>surefire-testng</artifactId>
						<version>2.22.0</version>
					</dependency>
				</dependencies>
				<configuration>
					<additionalClasspathElements>
						<additionalClasspathElement>src/test/java/</additionalClasspathElement>
					</additionalClasspathElements>
					<!-- TestNG Test Fails when executed from command line with message
						"Cannot use a threadCount parameter less than 1" 
						Works when threadCount is explicitly specified 
						https://gist.github.com/juherr/6eb3e93e2db33979b7e90b63ddadc888-->
					<threadCount>5</threadCount>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Note that I am using 2.0.0-beta.5 version of PowerMock. This version supports Java 10, however, it’s still in beta so there might be some issues present in complex cases. When I tried to use current stable version 1.7.x, I got the following errors.

java.lang.NoSuchMethodError: org.mockito.internal.handler.MockHandlerFactory.createMockHandler(Lorg/mockito/mock/MockCreationSettings;)Lorg/mockito/internal/InternalMockHandler;
	at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:114)
	at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:69)
	at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:46)
	at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:73)

Here are GitHub issues opened for this exception - issue1 and issue2. Let’s create a simple class with a static method.

package com.journaldev.mockito.staticmethod;

public class Utils {

	public static boolean print(String msg) {
		System.out.println("Printing "+msg);
		return true;
	}
}

JUnit Mockito PowerMock Example

We need to do the following to integrate PowerMock with Mockito and JUnit 4.

  • Annotate test class with @RunWith(PowerMockRunner.class) annotation.
  • Annotate test class with @PrepareForTest and provide classed to be mocked using PowerMock.
  • Use PowerMockito.mockStatic() for mocking class with static methods.
  • Use PowerMockito.verifyStatic() for verifying mocked methods using Mockito.

Here is a complete example of mocking static method using Mockito and PowerMock in JUnit test case.

package com.journaldev.mockito.staticmethod;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Utils.class)
public class JUnit4PowerMockitoStaticTest{

	@Test
	public void test_static_mock_methods() {
		PowerMockito.mockStatic(Utils.class);
		when(Utils.print("Hello")).thenReturn(true);
		when(Utils.print("Wrong Message")).thenReturn(false);
		
		assertTrue(Utils.print("Hello"));
		assertFalse(Utils.print("Wrong Message"));
		
		PowerMockito.verifyStatic(Utils.class, atLeast(2));
		Utils.print(anyString());
	}
}

TestNG Mockito PowerMock Example

For TestNG test cases, we don’t need to use @RunWith annotation. We need test classes to extend PowerMockTestCase so that PowerMockObjectFactory is used to create test class instance.

package com.journaldev.mockito.staticmethod;

import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;

import static org.mockito.Mockito.*;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.Test;

@PrepareForTest(Utils.class)
public class TestNGPowerMockitoStaticTest extends PowerMockTestCase{

	@Test
	public void test_static_mock_methods() {
		PowerMockito.mockStatic(Utils.class);
		when(Utils.print("Hello")).thenReturn(true);
		when(Utils.print("Wrong Message")).thenReturn(false);
		
		assertTrue(Utils.print("Hello"));
		assertFalse(Utils.print("Wrong Message"));
		
		PowerMockito.verifyStatic(Utils.class);
		Utils.print("Hello");
		PowerMockito.verifyStatic(Utils.class, times(2));
		Utils.print(anyString());
	}
}

Summary

PowerMock provides extended features for Mockito, one of them is the ability to test static methods. It’s easily integrated with JUnit 4 and TestNG. However, there is no near-term support plan for JUnit 5.

You can download the complete project from our GitHub Repository.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Pankaj

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
August 26, 2020

Can you add static void method please.

- asdfsad

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    July 7, 2020

    Nice but I want to know how can we do the same with spring boot 2.3 and higher version.

    - amar

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      June 24, 2020

      Hello Pankaj , For mocking static methods , if we use PowerMockito , it will increse the memory consumption and soon we will get outofmemory on the application For mocking the static methods we can also use the approach of wrapping the static methods call in a sub -method and mocking it using spy . Hope I am correct .

      - Sukriti Shrivastava

        Try DigitalOcean for free

        Click below to sign up and get $200 of credit to try our products over 60 days!

        Sign up

        Join the Tech Talk
        Success! Thank you! Please check your email for further details.

        Please complete your information!

        Become a contributor for community

        Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

        DigitalOcean Documentation

        Full documentation for every DigitalOcean product.

        Resources for startups and SMBs

        The Wave has everything you need to know about building a business, from raising funding to marketing your product.

        Get our newsletter

        Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

        New accounts only. By submitting your email you agree to our Privacy Policy

        The developer cloud

        Scale up as you grow — whether you're running one virtual machine or ten thousand.

        Get started for free

        Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

        *This promotional offer applies to new accounts only.