How can I mock a private static method with PowerMockito?
This is the same question as asked here. Unfortunately the accepted answer doesn't work for me. I have a static utility class with private methods that I need to test. I find that when I mock methods like this:
PowerMockito.spy(StaticUtil.class);
PowerMockito.when(StaticUtil.class, "getSomethingMethod", someObjectArray, someStringArray, aBoolean, someList).thenReturn(anotherList);
I am getting a null pointer exception because it is actually being thrown getSomethingMethod()
. When I debug I see that it is not called when I run the method I am trying to test, but it works when I set up the layout. Based on this site, it looks like this is what should happen when you create a layout in this format.
So, I am trying to set up the layout this way:
PowerMockito.spy(StaticUtil.class);
PowerMockito.doReturn(anotherList).when(StaticUtil.getSomethingMethod( someObjectArray, someStringArray, aBoolean, someList);
However, I get a message from Eclipse saying that I need to change my visibility getSomethingMethod()
to the public. Isn't one of the great benefits of using PowerMockito that you can mock private methods? I need to mock this method private static
(without actually calling the method during setup).
source to share
You must use the exact syntax they define in the answer you provided . This syntax doReturn(returnValue).when(Class, String, arguments);
. None of the examples provided here use this example.
Here are some extended explanations. I've demonstrated this:
Trying to run tests in this class:
package org.test.stackoverflow;
import java.util.Collections;
import java.util.List;
public class StaticUtil {
public static void Wrapper() {
getSomethingMethod(null, null, false, Collections.<String>emptyList());
}
private static List<String> getSomethingMethod(Object[] obj,
String[] str, boolean flag, List<String> aList){
System.out.println("I happen!");
return aList;
}
}
If the method itself is called, we will see I happen!
. If it doesn't, we won't.
Then I use this test class:
package org.test.stackoverflow;
import java.util.List;
import org.junit.runner.RunWith;
import org.junit.*;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(org.test.stackoverflow.StaticUtil.class)
public class StaticUtilTest {
Object[] someObjectArray;
String[] someStringArray;
boolean aBoolean;
List<String> someList;
List<String> anotherList;
@Test
public void testWhenClassStringMethod() throws Exception {
System.out.println("Beginning Test when(Class klass, String method name).doReturn(result)");
PowerMockito.spy(StaticUtil.class);
PowerMockito.when(StaticUtil.class, "getSomethingMethod", someObjectArray, someStringArray, aBoolean, someList).thenReturn(anotherList);
System.out.println("End Test when");
}
@Test
public void testDoReturnActualMethod() throws Exception {
PowerMockito.spy(StaticUtil.class);
// This doesn't compile as you've correctly stated
// PowerMockito.doReturn(anotherList).when(StaticUtil.getSomethingMethod(someObjectArray, someStringArray, aBoolean, someList);
}
@Test
public void testDoReturnClassStringMethod() throws Exception {
System.out.println("Beginning Test doReturn().when(Class klass, String method name");
PowerMockito.spy(StaticUtil.class);
PowerMockito.doReturn(anotherList).when(StaticUtil.class, "getSomethingMethod", someObjectArray, someStringArray, aBoolean, someList);
System.out.println("End Test doReturn");
}
}
So, if it prints I happen
, we were using the wrong syntax. When I run this program, we get:
Beginning Test when(Class klass, String method name).doReturn(result)
I happen!
End Test when
Beginning Test doReturn().when(Class klass, String method name)
End Test doReturn
Hence, you must use the syntax in the third test .
Note: This example uses static, empty arguments; obviously, you should configure your example to use Match Arguments as usual for your application.
source to share
when you set expectations on a mock object, you must use match arguments like Matchers.any () or Matchers.anyString (), but not actual arguments.
See my answer to J-Unit Test for details : Make static method void on class Exception
There is a potential problem with durron597's answer : the syntax in 'testDoReturnClassStringMethod' is not being mocked properly. In this method, it tried to mock the StaticUtil class, but didn't call the test method wrapper. See Example
@Test
public void testDoReturnClassStringMethod() throws Exception {
System.out.println("Beginning Test doReturn().when(Class klass, String method name");
PowerMockito.spy(StaticUtil.class);
PowerMockito.doReturn(anotherList).when(StaticUtil.class, "getSomethingMethod", someObjectArray, someStringArray, aBoolean, someList);
StaticUtil.Wrapper();
System.out.println("End Test doReturn");
}
The result for this is
Beginning Test doReturn().when(Class klass, String method name
I happen!
End Test doReturn
"Happen!" printed. mock is not configured correctly.
The correct way to taunt:
@Test
public void testDoReturnWithProperMock() throws Exception {
System.out.println("Beginning Test doReturn().when(Class klass, String method name");
PowerMockito.spy(StaticUtil.class);
PowerMockito.doReturn(anotherList).when(StaticUtil.class, "getSomethingMethod", Matchers.anyObject(), Matchers.anyObject(), Matchers.anyBoolean(), Matchers.anyList());
StaticUtil.Wrapper();
System.out.println("End Test doReturn");
}
What is the result for:
Beginning Test doReturn().when(Class klass, String method name
End Test doReturn
source to share