Reputation: 397
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).
Upvotes: 4
Views: 15339
Reputation: 3087
when you set the expectations on mock object, you have to use argument matchers like Matchers.any() or Matchers.anyString() but not actual arguments.
For more details, see my answer to J-Unit Test: Make static void method in final class throw exception
There is a potential issue with durron597's answer: the syntax in 'testDoReturnClassStringMethod' is not mocked properly. In that method, he tried to mock StaticUtil class but didn't call the test method wrapper. See the 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
'I happen!' is printed. mock is not configured properly.
The correct way of mocking is:
@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");
}
For which the result is:
Beginning Test doReturn().when(Class klass, String method name
End Test doReturn
Upvotes: -3
Reputation: 32323
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.
Upvotes: 8