I am trying to unit test a method using JUnit4. The method under test is calling another private method and I would like to mock it using PowerMockito.
My method is like below:
Class MyClass {
public List<String> myMethod(String name) throws IOException
{
... Few lines of code for setting variables
List<String> result = myPrivateMethod(a, b);
... Few more lines of code..
result.addAll(myPrivateMethod(c, d));
return result;
}
private List<String> myPrivateMethod(String a, String b) {
.....
}
}
My unit test method to test above code is as below:
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class TestClass {
@Test
public void testMyMethod() throws Exception {
MyClass myClass = PowerMockito.spy(new MyClass());
PowerMockito.doReturn(new ArrayList<String>(){{add("temp");}}).when(myClass, "myPrivateMethod", "a", "b");
List<String> list = myClass.myMethod("someName");
assertEquals(list.size(), 1);
}
}
I am expecting line PowerMockito.doReturn(new ArrayList(){{add("temp");}}).when(myClass, "myPrivateMethod", "a", "b"); to return list of size 1. I verified that execution is not going into private method but I am not getting List with one value added.
What is wrong in the above unit test code and why I am getting null instead of populated List as metioned in PowerMockito.doReturn() method?
In your test you are invoking myMethod
which, in turn, invokes myPrivateMethod
twice, see:
List<String> result = myPrivateMethod(a, b);
...
result.addAll(myPrivateMethod(c, d));
But your test only mocks one call to myPrivateMethod
so the flow looks like this:
myMethod
->myPrivateMethod
where the arguments area, b
- this is mocked andmyPrivateMethod
returns "temp"myMethod
->myPrivateMethod
where the arguments arec, d
- this is not mocked and hencemyPrivateMethod
is executed
In order for this assertion to pass: assertEquals(list.size(), 1);
you'll need to rework your test to mock the second call to myPrivateMethod
. In addition, the reference to "returns null" suggest that the when
block here: .when(myClass, "myPrivateMethod", "a", "b")
did not match the actual parameters supplied in your myMethod
.
Here's a working example:
public class MyClass {
public List<String> myMethod(String name) throws IOException {
List<String> result = myPrivateMethod("a", "b");
result.addAll(myPrivateMethod("c", "d"));
return result;
}
private List<String> myPrivateMethod(String a, String b) {
List<String> r = new ArrayList<>();
r.add(a);
r.add(b);
return r;
}
}
@Test
public void testMyMethod() throws Exception {
MyClass myClass = PowerMockito.spy(new MyClass());
PowerMockito.doReturn(new ArrayList<String>(){{add("temp");}})
.when(myClass, "myPrivateMethod", "a", "b");
PowerMockito.doReturn(new ArrayList<String>())
.when(myClass, "myPrivateMethod", "c", "d");
List<String> list = myClass.myMethod("someName");
assertEquals(1, list.size());
assertEquals("temp", list.get(0));
}
The above example test passes with the following:
- junit: 4.12
- powermock-module-junit4: 2.0.2
- powermock-api-mockito2: 2.0.2