如何为调用API的方法编写JUnit测试?

鳄梨 :

我必须为调用API的类编写测试,然后处理响应。该类具有两个公共职能和一个私人职能。第一个公共方法获取ID列表。在每个ID的循环中调用第二个公共方法,以获取与ID关联的详细信息。在第二个公共方法内部调用了私有方法,因为基于id的获取详细信息的调用是异步进行的。

我是JUnits的新手,虽然我知道我不应该测试API调用,而只是测试我的函数,但我仍然不了解单元测试应该断言的内容。

以下是我的功能:

public List<Integer> fetchVehicleIds(String datasetId) throws ApiException {

    VehiclesApi vehiclesApi = new VehiclesApi();

    List<Integer> vehicleIds;
    vehicleIds = vehiclesApi.vehiclesGetIds(datasetId).getVehicleIds();

    return vehicleIds;
}

 public List<VehicleResponse> fetchVehicleDetails(String datasetId, List<Integer> vehicleIds) throws InterruptedException, ApiException {

    CountDownLatch latch = new CountDownLatch(vehicleIds.size());
    List<VehicleResponse> vehiclesList = new ArrayList<>();

    for (Integer vehicleId: vehicleIds) {
        populateEachVehicleDetail(datasetId, vehicleId, vehiclesList, latch);
    }

    latch.await();

    return vehiclesList;
}

private void populateEachVehicleDetail(String datasetId, Integer vehicleId, List<VehicleResponse> vehiclesList, CountDownLatch latch) throws ApiException {

    ApiCallback<VehicleResponse> vehicleResponseApiCallback = new ApiCallback<VehicleResponse>() {
        @Override
        synchronized public void onSuccess(VehicleResponse result, int statusCode, Map<String, List<String>> responseHeaders) {
            vehiclesList.add(result);
            latch.countDown();
        }
    };

    VehiclesApi vehiclesApi = new VehiclesApi();
    vehiclesApi.vehiclesGetVehicleAsync(datasetId,vehicleId,vehicleResponseApiCallback);

}

根据我到目前为止所做的研究,我认为我必须使用模拟程序模拟API调用吗?我还不清楚如何对该功能进行单元测试。

大卫:

这两个语句确实是您要在单元测试中隔离的东西:

private void populateEachVehicleDetail(String datasetId, Integer vehicleId, List<VehicleResponse> vehiclesList, CountDownLatch latch) throws ApiException {
....
    VehiclesApi vehiclesApi = new VehiclesApi();
    vehiclesApi.vehiclesGetVehicleAsync(datasetId,vehicleId,vehicleResponseApiCallback);
...
}

1)使依赖成为可模拟的

但是您只能模拟可以从类的客户端设置的内容。
这里的API是一个局部变量。因此,您应该更改类以公开依赖关系,例如在构造函数中。
这样,您可以轻松地对其进行嘲笑。

2)使您的模拟不返回结果,而是调用回调。

在同步调用上下文中,您要模拟返回的结果。
在带有回调的异步调用上下文中,情况有所不同。的确回调不会返回到调用者,而是会调用回调来提供调用结果,因此这里您想要的是模拟API会onSuccess()使用模拟参数来调用回调,这些参数代表了单元测试的数据集:

@Override
synchronized public void onSuccess(VehicleResponse result, int statusCode, Map<String, List<String>> responseHeaders) {
    vehiclesList.add(result);
    latch.countDown();
}

在单元测试中,应该以这种方式模拟每个预期调用的回调:

@Mock
VehiclesApi vehiclesApiMock;
// ...

// when the api method is invoked with the expected dataSetId and vehicleId
Mockito.when(vehiclesApiMock.vehiclesGetVehicleAsync(Mockito.eq(datasetId), Mockito.eq(vehicleId),
                                                 Mockito.any(ApiCallback.class)))
       // I want to invoke the callback with the mocked data
       .then(invocationOnMock -> {
           ApiCallback<VehicleResponse> callback = invocationOnMock.getArgument(2);
           callback.onSuccess(mockedVehicleResponse, mockedStatusCode,
                              mockedResponseHeaders);
           return null; // it is a void method. So no value to return in T then(...).
       });

我认为缺少演员表,ApiCallback但您应该有整体想法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章