繁体   English   中英

如何使用PowerMockito模拟私有静态方法?

[英]How can I mock a private static method with PowerMockito?

这是与此处相同的问题。 不幸的是,接受的答案对我不起作用。 我有一个静态实用程序类,我需要测试私有方法。 我发现当我模仿这样的方法时:

PowerMockito.spy(StaticUtil.class);
PowerMockito.when(StaticUtil.class, "getSomethingMethod", someObjectArray, someStringArray, aBoolean, someList).thenReturn(anotherList);

我得到一个空指针异常,因为实际上正在调用getSomethingMethod() 当我调试时,我发现当我运行我正在尝试测试的方法时它没有被调用,但是当我设置模拟时它正在运行。 基于此站点,看起来这就是以这种格式创建模拟时应该发生的事情。

那么我尝试以这种方式设置模拟:

PowerMockito.spy(StaticUtil.class);        
PowerMockito.doReturn(anotherList).when(StaticUtil.getSomethingMethod( someObjectArray, someStringArray, aBoolean, someList);

但是,我从Eclipse得到一个错误,说我需要将getSomethingMethod()的可见性更改为public。 使用PowerMockito可以模拟私有方法的一大好处是什么? 我需要模拟这个private static方法(在安装过程中没有实际调用方法)。

您必须使用他们在您链接的答案中指定的确切语法 该语法是doReturn(returnValue).when(Class, String, arguments); 您在此处提供的示例都没有使用该示例。


这是一些扩展的解释。 我把一个示例测试框架放在一起来演示这个:

试图在这个类上运行测试:

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;
  }
}

如果方法本身被调用,我们会看到I happen! 如果没有,我们不会。

然后,我使用这个测试类:

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");
  }
}

所以,如果打印I happen ,那么我们使用了错误的语法。 当我运行这个程序时,我们得到:

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

因此,您必须在第三个测试中使用语法

注意:此示例使用静态,空参数; 显然,您应该将示例配置为正常使用Argument Matchers ,以适合您的应用程序。

当你设置对mock对象的期望时,你必须使用像Matchers.any()或Matchers.anyString()这样的参数匹配器,而不是实际的参数。

有关更多详细信息,请参阅我对J-Unit Test的回答:在final class throw异常中创建static void方法

durron597的答案存在潜在问题:'testDoReturnClassStringMethod'中的语法未被正确模拟。 在该方法中,他试图模拟StaticUtil类,但没有调用测试方法包装器。 查看示例

@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");
}

结果是

Beginning Test doReturn().when(Class klass, String method name
I happen!
End Test doReturn

“我发生了!” 打印出来。 mock配置不正确。

正确的嘲弄方式是:

@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");

}

结果如下:

Beginning Test doReturn().when(Class klass, String method name
End Test doReturn

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM