This is the same question as found here. Unfortunately, the accepted answer isn't working 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'm getting a null pointer exception because the getSomethingMethod()
is actually being called. When I debug, I see that it isn't being called when I run the method I'm trying to test, but it is running when I am setting up the mock. Based on this site, it looks like that is what is supposed to happen when you create the mock in this format.
So then I try to set up the mock this way:
PowerMockito.spy(StaticUtil.class);
PowerMockito.doReturn(anotherList).when(StaticUtil.getSomethingMethod( someObjectArray, someStringArray, aBoolean, someList);
However, I am get an error from Eclipse that says I need to change the visibility of getSomethingMethod()
to public. Isn't one of the big benefits of using PowerMockito that you can mock private methods? I need to mock this private static
method (without actually calling the method during setup).
You have to use the exact syntax that they specify in the answer you linked. That syntax is doReturn(returnValue).when(Class, String, arguments);
. Neither of the examples you've provided here use that example.
Here's some extended explanation. I've thrown together a sample test framework to demonstrate this:
Trying to run tests on 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 gets invoked, we'll 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
, then we've used 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
Therefore, you must use the syntax in the third test.
Note: this example uses static, empty arguments; obviously you should configure your example to use Argument Matchers as normal as appropriate for your application.