【问题标题】:How can I mock private static method with PowerMockito?如何使用 PowerMockito 模拟私有静态方法?
【发布时间】:2014-10-24 23:44:27
【问题描述】:

我正在尝试模拟私有静态方法anotherMethod()。见下面的代码

public class Util {
    public static String method(){
        return anotherMethod();
    }

    private static String anotherMethod() {
        throw new RuntimeException(); // logic was replaced with exception.
    }
}

这是我的测试代码

@PrepareForTest(Util.class)
public class UtilTest extends PowerMockTestCase {

        @Test
        public void should_prevent_invoking_of_private_method_but_return_result_of_it() throws Exception {

            PowerMockito.mockStatic(Util.class);
            PowerMockito.when(Util.class, "anotherMethod").thenReturn("abc");

            String retrieved = Util.method();

            assertNotNull(retrieved);
            assertEquals(retrieved, "abc");
        }    
}

但是我运行的每一个图块都会出现这个异常

java.lang.AssertionError: expected object to not be null

我想我在嘲笑东西方面做错了什么。有什么想法可以解决吗?

【问题讨论】:

    标签: java unit-testing mockito


    【解决方案1】:

    为此,您可以使用PowerMockito.spy(...)PowerMockito.doReturn(...)

    此外,您必须在测试类中指定 PowerMock 运行器,并准备该类进行测试,如下所示:

    @PrepareForTest(Util.class)
    @RunWith(PowerMockRunner.class)
    public class UtilTest {
    
       @Test
       public void testMethod() throws Exception {
          PowerMockito.spy(Util.class);
          PowerMockito.doReturn("abc").when(Util.class, "anotherMethod");
    
          String retrieved = Util.method();
    
          Assert.assertNotNull(retrieved);
          Assert.assertEquals(retrieved, "abc");
       }
    }
    

    希望对你有帮助。

    【讨论】:

    • 如果您已经使用 PowerMock 运行器指定了一个类,请添加第二个,如下所示:@PrepareForTest({First.class, Util.class})
    • String retrieved = Util.anotherMethod(); 静态方法的名称不是 method 它是 anotherMethod .
    • @Stevers method() 是从测试中调用的公共静态方法。 anotherMethod() 是模拟方法。答案是正确的,请再次检查OP。
    • 解决方案并没有真正提到原始解决方案有什么问题。最初的解决方案是使用一个模拟,这意味着一个完整的假对象,其中没有定义方法。作者只为方法“anotherMethod”定义了它在被调用时的行为方式。但是他没有为方法“方法”定义相同的方式。这就是为什么调用“method”会返回 null 甚至永远不会调用“anotherMethod”的原因。使用间谍我们使用的是真实的对象,所有的方法都是真实的方法。另一种解决方案是使用模拟并使用 .callRealMethod 作为“方法”。
    【解决方案2】:

    如果 anotherMethod() 将任何参数作为 anotherMethod(parameter),则该方法的正确调用将是:

    PowerMockito.doReturn("abc").when(Util.class, "anotherMethod", parameter);
    

    【讨论】:

      【解决方案3】:

      我不确定您使用的是哪个版本的 PowerMock,但对于更高版本,您应该使用@RunWith(PowerMockRunner.class) @PrepareForTest(Util.class)

      说到这一点,我发现使用 PowerMock 确实存在问题,并且肯定是设计不佳的标志。如果您有时间/机会更改设计,我会先尝试这样做。

      【讨论】:

      • 没有。对于TestNG,我需要使用我的注释。
      • 对于那些需要使用不同的跑步者因此无法使用 PowerMockRunner 的人的注意事项,您可以使用 @Rule 注释:``` @Rule public PowerMockRule rule = new PowerMockRule(); ```
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 1970-01-01
      • 2017-03-07
      相关资源
      最近更新 更多