当前位置: 首页 > 知识库问答 >
问题:

Mocking私有空方法给出AssertionError

卫建义
2023-03-14

我正在使用Powermock为Jersey web服务构建测试用例,并试图模拟数据库函数调用,特别是PUT和POST调用。然而,我在这方面遇到了一些问题。

下面是其中一个web服务调用的样子:

@Path("/v1.0.0")
public class WebService {

    @POST
    @Path("application")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response createApplication(@QueryParam("callback") String callbackFunction, String body)
            throws NamingException, SQLException, IllegalStateException, CacheException, UnknownHostException,
            IOException {
        String query = "exec spInsertApplication ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?";
        String[] params = new String[16];
        JSONObject json = (JSONObject) JSONValue.parse(body);
        params[0] = json.get("name").toString();
        params[4] = json.get("software").toString();
        params[14] = json.get("customerid").toString();
        //Null checks for other params

        runUpdateQuery(query, params);

        return generateResponse(callbackFunction, null);
    }

    private void runUpdateQuery(String query, String[] queryParameters) {
        //Handles running DB query
    }
}

以及我的测试用例当前的样子:

@RunWith(PowerMockRunner.class)
@PrepareForTest(WebService.class)
@PowerMockIgnore( {"javax.management.*"}) 
public class TestRestWebService {

    @Test
    public void test_createApplication_returns_http_success() throws Exception {
        String query = "exec spInsertApplication ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?";
        String[] params = new String[16];
        params[0] = "test_app_name";
        params[4] = "test_software";
        params[14] = "23";

        WebService tested = createPartialMockAndInvokeDefaultConstructor(WebService.class, "runUpdateQuery");
        expectPrivate(tested, "runUpdateQuery", query, params).andAnswer(
                new IAnswer<Void>() {
                    @Override
                    public Void answer() throws Throwable {
                        return null;
                    }
                });
        replay(tested);

        String JSONString = "{\"name\":\"test_service_name\",\"software\":\"test_software\",\"customerid\":\"23\"}";
        Response output = tested.createApplication("CALLBACK", JSONString);
        verify(tested);
        assertTrue(output.getStatus() == 200);
    }
}

当运行时,这给了我一个断言错误:

意外的方法调用WebService。runUpdateQuery(“exec spInsertApplication,[“测试服务名称”,空,空,空,“测试软件”,空,空,空,空,空,空,空,空,空,空,空,23,空]:

网络服务。runUpdateQuery(“exec spInsertApplication,[“测试服务名称”,null,null,null,“测试软件”,null,null,null,null,null,null,null,null,null,null,null,null,23,null]):预期值:1,实际值:0

在进一步挖掘之后,我发现原因很可能与PowerMock比较字符串数组的方式有关。所以我也尝试了一种更通用的方法,因为该函数通过使用EasyMock返回void。anyString()EasyMock。isA(String[].class)代替了我的两个参数,但这会导致NullPointerException。下面是stacktrace的前几行:

java.lang.NullPointerException
    at java.lang.Class.isAssignableFrom(Native Method)
    at org.powermock.reflect.internal.WhiteboxImpl.checkIfParameterTypesAreSame(WhiteboxImpl.java:2432)
    at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1934)
    at org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:1025)
    at org.powermock.reflect.internal.WhiteboxImpl.findMethodOrThrowException(WhiteboxImpl.java:948)

我如何正确地模拟这个私有无效方法来避免测试期间的数据库调用?

共有1个答案

卢景澄
2023-03-14

在深入研究这个测试和文档几次后,我发现expectPrivate调用没有找到我的方法。下面是我如何指定函数的:

expectPrivate(tested, WebService.class.getDeclaredMethod("runUpdateQuery", String.class, String[].class),
        EasyMock.anyString(), EasyMock.aryEq(params)).andAnswer(new IAnswer<Void>() {
    @Override
    public Void answer() throws Throwable {
        return null;
    }
});

这还允许我在使用泛型类型定义函数时,与函数最初希望调用的数组进行比较。

 类似资料:
  • 我试图模仿一个私有方法,如下所示。但是,在第4行,JUnit正在调用相关的validateLanguage方法,并且由于私有方法validateLanguage在调用其他方法时引发了异常,因此没有返回模拟值。我的理解是,使用PowerMock的JUnit应该跳过validateLanguage实际实现的调用。有人能澄清一下吗?

  • 我找到了使用ReflectionUtils的方法 现在我想驱动这个方法返回一个指定的值。通常,如果< code>myMethod是公共的,我会写例如 但是有没有可能用私有的myMethod来实现呢?< br >当我打电话时 我有Java . lang . reflect . invocationtargetexception .我读过关于PowerMock的文章,但是我想知道是否只有Mockito

  • 我有一门课看起来像这样: 我想使用Mockito和Powermock为此编写一个单元测试。我知道我可以这样模仿私有方法: 但是我如何告诉它抛出异常呢?我知道会是这样的: 那里有什么? 请注意,异常是一个私有内部类,因此我不能只执行,因为从单元测试中无法访问。

  • Mocking resttemplate.exchange()不起作用。restTemplate.exchange()mocking的响应在BDS适配器类中给出null值。我的测试用例由于BDSAdapter类中的空指针异常而失败。(response.getStatusCodeValue()提供空指针异常。.mockito提示) 未使用...->at com..policydetails_adap

  • 问题内容: 要使用公共方法创建JavaScript类,我需要执行以下操作: 这样,我班的用户可以: 如何创建一个私有方法,该私有方法可以由和方法调用,但不能由该类的用户外部调用? 换句话说,我希望我的方法实现能够做到: 但这不起作用: 如何将其定义为私有方法,使两者都适用? 我已经读过Doug Crockford的文章 几次,但似乎公共方法不能调用“私有”方法,而外部可以调用“特权”方法。 问题答

  • 我试图模拟一个私有方法(executeGetRequest),在我声明要为私有方法返回的模拟的那一行中,私有方法实际上是用null参数执行的,因此抛出了一个NullPointerException。 VlcPlayerMinimal。爪哇: VlcPlayerMinimalTest。爪哇: 堆栈跟踪: 它似乎PowerMockito实际上是调用的方法,我试图在行PowerMockito.do返回(