我对测试完全是个新手。
假设有一个简单的方法,它向某个第三方API发送请求,并返回一个从接收到的json构造的对象:
public Object getAirQualityIndex(int id) {
try {
String stationInfoUrl = aqIndexUrlPattern.replace("{id}", String.valueOf(id));
HttpRequest stationRequest = HttpRequest.newBuilder()
.uri(URI.create(stationInfoUrl))
.GET()
.build();
HttpResponse<String> stationResponse = HttpClient.newBuilder()
.build()
.send(stationRequest, HttpResponse.BodyHandlers.ofString());
if (stationResponse.statusCode() != 200) {
throw new RuntimeException("Air Quality Index is currently unavailable, " +
"status code " + stationResponse.statusCode());
}
return new ObjectMapper().readValue(stationResponse.body(), new TypeReference<>() {});
} catch (Exception e) {
throw new RuntimeException("failed to get station measures information", e);
}
}
它可以分为几种私人的方法,但在这种情况下,我认为它不会改变问题的本质。
现在我想为这个方法编写一个单元测试,我是否正确理解了为此我需要为依赖项创建一个Mock,例如:HttpResponse.statusCode()
,HttpResponse.body()
,ObjectMapper().readValue(...)
?但在我看来,整个测试将只是检查if (statusCode != 200)
是否工作,因为我将用Mocks替换其他所有内容,这样就不会失败,这样的测试有任何实际意义吗?
接下来,有一个方法允许您将生成的对象保存到一个文件中,以什么形式保存并不重要,但假设它是pdfusing itext7
:
public void writeAirQualityIndexAsPdf(Object aqIndex, Path destPath) throws IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(destPath.toFile()));
Document document = new Document(pdf);
String aqIndexYaml = new YAMLMapper()
.writerWithDefaultPrettyPrinter()
.withRootName("AirQualityIndex")
.writeValueAsString(aqIndex);
//replaced spaces with \u00A0 to prevent itext7 to trim whitespaces
document.add(new Paragraph(aqIndexYaml.replaceAll(" ", "\u00A0")));
document.close();
}
我这里的代码都不多,如果全部替换成Mocks就可以测试了,甚至可以重写成一行程序......那么我该怎么测试这个方法呢?
也许我只是误解了单元测试的一些想法,不值得为每个第三方调用创建一个Mock?
1条答案
按热度按时间92dk7w1h1#
在这种情况下,你可以使用一些像WireMock这样的库进行单元测试。这将帮助你用不同的响应代码和主体重现行为。同样,你可以使用WireMockAssert请求头和url。