我必须为调用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] 删除。
我来说两句