【问题标题】:How do I mock static method that calls other private static methods?如何模拟调用其他私有静态方法的静态方法?
【发布时间】:2017-10-08 12:36:43
【问题描述】:

如何在下面模拟这个调用另一个私有静态方法的方法?

public class testA {
    public static JSONObject retrieveOrder(String orderId)
                throws Exception {
            String url = "/contract/"; 
            JSONObject order = new JSONObject();
            order.put("orderId", orderId);  
            return orderPOST(url, order);
        }

    private static orderPOST(String url, JSONObject order) {
        return orderPOSTString(url, order.toString());
    }

    private static orderPOSTString (String url, String order) {
         //do another call to method which will return JSONObject
    }
}

我怎么能只模拟 retrieveOrder 方法,因为我不关心这些私有方法中的任何一个?至于那些私有的静态方法,我不能修改它们中的任何一个,所以必须按原样接受它们。

这是我的测试:

@Test
    public void testRetrieveOrderMethod() throws Exception {
        String url = "/contract/"; 
        JSONObject order = new JSONObject();
        order.put("orderId", orderId);  
        PowerMockito.spy(testA.class);
        PowerMockito.doReturn(url, order.toString()).when(testA.class, "orderPOST", Matchers.any(), Matchers.any());
        JSONObject retrieved = testA.retrieveOrder("12345");
    }  

如果我在这里遗漏了什么,请告诉我。我不断收到NullPointerException,因为我怀疑它实际上是在调用那些私有方法。

【问题讨论】:

  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建minimal reproducible example
  • 事情是:甚至你的被测类没有编译!这两个静态方法缺少返回类型。首先在这里提出合理的输入!并清楚说明你打算做什么

标签: java unit-testing mockito powermockito


【解决方案1】:

在您的代码中,when(testA.class, "orderPOST"... 正在模拟 orderPost 方法。

如果您只想模拟 retrieveOrder 方法而忽略其他方法,您的测试类应该是:

@RunWith(PowerMockRunner.class) // needed for powermock to work
// class that has static method and will be mocked must be in PrepareForTest
@PrepareForTest({ testA.class })
public class MyTestClass {

    @Test
    public void testRetrieveOrderMethod() throws Exception {
        // JSON object you want to return
        JSONObject order = new JSONObject();
        order.put("orderId", "whatever value you want to test");

        PowerMockito.spy(testA.class);
        // retrieveOrder will return order object
        PowerMockito.doReturn(order).when(testA.class, "retrieveOrder", Mockito.anyString());

        // call static method
        JSONObject retrieved = testA.retrieveOrder("12345");

        // do the assertions you need with retrieved
    }
}

您也可以将spydoReturn 更改为:

PowerMockito.mockStatic(testA.class);
Mockito.when(testA.retrieveOrder(Mockito.anyString())).thenReturn(order);

两者的工作方式相同。

【讨论】:

  • 我已经更新了我的测试代码,但现在我遇到了两个不同的错误,这取决于我如何模拟它。 1.有没有一种方法我不必包含在 PrepareForTest 中。如果我在 PrepareForTest 中包含 testA.class,它将无法用于代码覆盖目的。 2. 但是如果我不包括在 PrepareForTest 中,我会得到 org.mockito.exceptions.misusing.UnfinishedStubbingException: Unfinished stubbing 在此处检测到:........ 3. 如果我更改为 mockStatic 以及何时,那么当然我得到了 org.powermock.api.mockito.ClassNotPreparedException。 4. Whitebox.invokeMethod 方法是什么?
  • 如果你想用PowerMockito模拟一个静态方法,你必须使用RunWithPrepareForTest(好像是mandatory)好像有一个bug with PowerMockito and code coverage,不知道是不是它已经(或将要)修复。我没用过Whitebox,不知道能不能用。
  • 我最终不得不运行这些私有静态方法,因为我无法找到忽略它们的方法。现在一切都对我有用。
猜你喜欢
  • 2012-07-14
  • 2014-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
相关资源
最近更新 更多