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).

+3


source to share


2 answers


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.

+6


source


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

      

-3


source







All Articles