[JAVA] Mock static methods with PowerMock

table of contents

  1. Procedure for building an environment for using PowerMock
  2. Mock and Spy in PowerMock
  3. Mock static methods with PowerMock ← Now here
  4. Mock the constructor with PowerMock
  5. Mock private methods with PowerMock
  6. Try using PowerMock's WhiteBox
  7. Disable static initializer in PowerMock

Overview

With PowerMock, you can set the return value of a static method to any value or return an exception.

Here, it is assumed that the static method of the Utility class (mocking class) called from the UseUtility class (test target class) is mocked.

Tested class

This is the class to be tested that is called from JUnit.

I am calling the static method of Utility class internally and want to set these return values and exceptions.

UseUtility.java


public class UseUtility {

	public String getMessage(String name) throws Exception {

		String trimmedName = Utility.trim(name);

		return "Hello, " + trimmedName + ".";
	}

	public boolean setUp() {

		Utility.clearDatabase();

		//abridgement

		return true;
	}
}

Mocking class

Mock it and define arbitrary behavior.

Utility.java


public class Utility {

	public static String trim(String string) throws Exception {
		//Unimplemented assumption
		return string;
	}

	public static void clearDatabase() {
		//Assumption of processing that you do not want to execute
	}
}

Test class

JUnit that calls the class under test.

To use PowerMock with JUnit, specify PowerMockRunner for @RunWith.

For @PrepareForTest, specify the class to mock. When mocking only static methods, it is not necessary to describe the calling class (test target class).

UseUtilityTest.java


@RunWith(PowerMockRunner.class)
@PrepareForTest(Utility.class)
public class UseUtilityTest {
    //abridgement
}

Example of use

doReturn Set the return value in the static method.

@Test(expected = Exception.class)
public void test_doThrow() throws Exception {
	//Preparation
	String name = "John ";
	Exception expected_exception = new Exception("error!");

	//Mocking
	PowerMockito.mockStatic(Utility.class);
	//Set mock class and exception
	PowerMockito.doThrow(expected_exception).when(Utility.class);
	//Set the method that returns the exception set in ↑
	Utility.trim(anyString());

	//Run
	UseUtility obj = new UseUtility();
	obj.getMessage(name);
}

doThrow Throw an exception with a static method.

@Test
public void test_doThrow() throws Exception {
	//Preparation
	String name = "John ";
	String expected_message = "error!";
	Exception expected_exception = new IllegalArgumentException(expected_message);

	//Mocking
	PowerMockito.mockStatic(Utility.class);
	//Set mock class and exception
	PowerMockito.doThrow(expected_exception).when(Utility.class);
	//Set the method that returns the exception set in ↑
	Utility.trim(anyString());

	//Run
	try {
		UseUtility obj = new UseUtility();
		obj.getMessage(name);
		fail();
	} catch (Exception e) {
		//Check the result
		assertEquals(expected_exception, e.getCause());
		assertEquals(expected_message, e.getMessage());
	}
}

doCallRealMethod Call the real method without setting a return value or exception in the static method.

@Test
public void test_doCallRealMethod() throws Exception {
	//Preparation
	String name = "John ";
	String expected = "Hello, John .";

	//Mocking
	PowerMockito.mockStatic(Utility.class);
	//Setting to call the mock class and the real thing
	PowerMockito.doCallRealMethod().when(Utility.class);
	//Set a method to call the real thing
	Utility.trim(anyString());

	//Run
	UseUtility obj = new UseUtility();
	String actual = obj.getMessage(name);

	//Check the result
	assertEquals(expected, actual);
}

doNothing Use this when you don't want to do anything with the static method.

@Test
public void test_doNothing() throws Exception {
	//Ready to run
	//Mocking
	PowerMockito.mockStatic(Utility.class);
	//Mock class and do nothing setting
	PowerMockito.doNothing().when(Utility.class);
	//Set a method that does nothing
	Utility.clearDatabase();

	//Run
	UseUtility obj = new UseUtility();
	boolean actual = obj.setUp();

	//Check the result
	assertTrue(actual);
}

thenReturn Set the return value in the static method.

@Test
public void test_thenReturn() throws Exception {
	//Preparation
	String name = "John ";
	String expected = "Hello, John.";

	//Mocking
	PowerMockito.mockStatic(Utility.class);
	//Set return value
	PowerMockito.when(Utility.trim(anyString())).thenReturn("John");

	//Run
	UseUtility obj = new UseUtility();
	String actual = obj.getMessage(name);

	//Check the result
	assertEquals(expected, actual);
}

thenThrow Throw an exception with a static method.

@Test(expected = Exception.class)
public void test_thenThrow() throws Exception {
	//Preparation
	String name = "John ";
	Exception expected_exception = new Exception("error!");

	//Mocking
	PowerMockito.mockStatic(Utility.class);
	//Set exception
	PowerMockito.when(Utility.trim(anyString())).thenThrow(expected_exception);

	//Run
	UseUtility obj = new UseUtility();
	obj.getMessage(name);
}

thenCallRealMethod Call the real method without setting a return value or exception in the static method.

@Test
public void test_thenCallRealMethod() throws Exception {
	//Preparation
	String name = "John ";
	String expected = "Hello, John .";

	//Mocking
	PowerMockito.mockStatic(Utility.class);
	//Setting to call the real thing
	PowerMockito.when(Utility.trim(anyString())).thenCallRealMethod();

	//Run
	UseUtility obj = new UseUtility();
	String actual = obj.getMessage(name);

	//Check the result
	assertEquals(expected, actual);
}

Validation of static methods

PowerMock provides verifyStatic for validating mocked static methods.

You can use Mockito's times, atLeast, asLeastOnce, etc. to verify the number of calls.

verifyStatic (Utility.class) is synonymous with verifyStatic (Utility.class, times (1)).

//Confirm that it was called once
PowerMockito.verifyStatic(Utility.class);
Utility.trim(anyString());

Recommended Posts

Mock static methods with PowerMock
Mock Enums with PowerMock
Mock the constructor with PowerMock
Mock static methods in Mockito 3.4
Mock only some methods with Spock
How to mock each case with PowerMock + Mockito1x
[Note] Methods ending with?
MOCK constructors of other classes with Spring MVC + PowerMock + Junit
[Java] JavaConfig with Static InnerClass
Mock and spy on PowerMock
Disable static initializer in PowerMock
Processing speed with and without static
[Ruby] Handle instance variables with instance methods
[Java] Test private methods with JUnit