Mocking private method call using PowerMockito returns null instead of returning List<String>: (Want not to execute private method)

Sagar Kansara :

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?

glytching :

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:

  1. myMethod -> myPrivateMethod where the arguments are a, b - this is mocked and myPrivateMethod returns "temp"
  2. myMethod -> myPrivateMethod where the arguments are c, d - this is not mocked and hence myPrivateMethod 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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=141070&siteId=1