【发布时间】:2021-08-26 14:49:31
【问题描述】:
我有以下方法。该方法使用 Jackson ObjectMapper 转换 json 字符串的内容。如果 json 格式错误,则会打印堆栈跟踪并将对象设置为 null:
public ObjectTransferData extractJacksonObjectsFromFile(String json) {
ObjectTransferData objectTransferData;
try {
objectTransferData = objectMapper.readValue(json, ObjectTransferData.class);
} catch (Exception e) {
e.printStackTrace();
objectTransferData = null;
}
return objectTransferData;
}
我为可能的格式错误的 json 字符串编写了 JUnit 单元测试,如下所示:
@Test
public void testExtractJacksonObjectsFromFile_malformedJson_expectNull(){
String malformedJson = "{";
ObjectTransferData result = myService.extractJacksonObjectsFromFile(malformedJson);
assertNull(result);
}
此测试通过。但它也将e.printStackTrace() 打印到我的终端中,这在测试执行期间掩盖了实际的重要日志。测试执行的读者可能会感到困惑。
我想知道如何解决这个问题。我想出了这些想法:
- 删除 try/catch 并抛出异常。这将允许我像这样编写测试,而不是在控制台中获取堆栈跟踪。
@Test
public void testExtractJacksonObjectsFromFile_malformedJson_expectException(){
String malformedJson = "{";
assertThrows(Exception.class, () ->
objectImportService.extractJacksonObjectsFromFile(malformedJson)
);
}
但缺点是实际应用程序现在会抛出此异常,并且不会通过 catch 块处理它来优雅地失败。
- 以某种方式抑制测试的异常记录。但这可能会导致在测试执行期间隐藏实际错误的日志。
这个question 有点相关,但没有完全回答我的问题。 我可以将所有测试堆栈跟踪重定向到像this 这样的文件,但我不想在测试执行期间重定向实际异常。 告诉特定测试不打印堆栈跟踪是理想的。
【问题讨论】:
-
this 线程的这个答案只接受这些日志。但我与许多可能会感到困惑并认为这些是实际例外的同事一起工作。
-
使用记录器,并将记录器配置为不作为测试的一部分打印。不相关,但考虑将返回更改为
Optional<ObjectTransferData>。 -
我刚刚通读了 Robert C. Martin 的 Clean Code 一书,在关于错误处理的章节中发现了这条建议:如果出现问题,不要编写返回
null的方法。而是抛出异常。所以我会改变我的函数来抛出异常。
标签: java unit-testing junit try-catch stack-trace