【问题标题】:Mocking private void method gives AssertionError模拟私有 void 方法给出 AssertionError
【发布时间】:2014-09-24 20:20: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);
    }
}

运行时这给了我一个 AssertionError 说:

意外的方法调用 WebService.runUpdateQuery("exec spInsertApplication ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?", ["test_service_name", null, null, null, "test_software", 空,空,空,空,空,空,空,空,空,“23”,空]):

WebService.runUpdateQuery("执行 spInsertApplication ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?", ["test_service_name", null, 空,空,“test_software”,空,空,空,空,空,空,空, 空,空,“23”,空]):预期:1,实际:0

在进行了更多挖掘之后,我发现原因很可能与 PowerMock 如何比较字符串数组有关。因此,我还尝试了一种更通用的方法,因为该函数无论如何都会返回 void,方法是使用 EasyMock.anyString()EasyMock.isA(String[].class) 代替我的两个参数,但这会导致 NullPointerException 。以下是该堆栈跟踪的前几行:

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)

如何正确模拟这个私有 void 方法以避免在测试期间调用数据库?

【问题讨论】:

    标签: java unit-testing powermock


    【解决方案1】:

    在深入研究了这个测试和文档几次后,我发现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;
        }
    });
    

    这也让我可以在使用泛型类型定义函数时与函数调用的数组进行比较,就像我最初想要的那样。

    【讨论】:

      猜你喜欢
      • 2014-09-21
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-03
      相关资源
      最近更新 更多