在代码中通常会看到日志记录功能:
public class A {
private static final Log LOG = LogFactory.getLog(A.class);
使用方法:
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throw e;
}
但我从来没有看到过这样的代码的单个单元测试。
当然我会测试抛出异常和异常类型,但是我应该编写测试来检查日志信息吗?我倾向于认为日志是系统行为的另一部分,所以在测试中涵盖它是合乎逻辑的。
假设我应该覆盖它,这意味着我应该改变我的原始代码以注入mock log并检查“error”方法是否被预期的消息调用。但是如果我的原始类是service并且它是由spring示例化的,我应该注入一些logger以及其他依赖项吗?
7条答案
按热度按时间v1uwarro1#
测试日志库不是由你决定的。但是测试当抛出异常时,你的类在正确的级别记录消息是值得的。你测试的是你的代码对日志库做了正确的事情。
要使上面的代码可测试,请使用依赖注入。这假设日志记录器实现了接口
ILog
。您将日志记录器作为构造函数参数传递给类A。然后测试代码将创建ILog
的模拟实现,并将其传递到构造函数中。上面的代码中没有显示异常是如何发生的,但可能是通过其他依赖对象。所以你也模拟它,并让它抛出异常。然后检查mockILog
调用了error
方法。也许你想检查它记录的消息,但这可能太过分了,通过使测试代码脆弱。jw5wzhpr2#
是的,我们应该在日志记录正在做一些需要的事情时测试日志记录。例如,您在一些外部应用程序中有钩子,它会扫描日志中的某些事件。在这种情况下,您当然希望确保日志记录已经完成。
当然,您不希望测试每个日志事件,我认为大多数情况下只应该测试ERROR(而不是所有)。
使用SLF4j等现代日志框架,您可以简单地注入一个自定义处理程序,该处理程序将事件存储在内存中,并且可以在之后对其进行Assert。
我现在想到的有两个:
SLF4JTesting:不需要修改日志配置,但需要注入日志工厂,这可能会导致代码修改。
SLF4J Test:没有slf4jtesting那么强大,而且似乎还没有开发,但可以很好地与现有代码一起工作。除了用于测试的日志记录器配置之外,没有任何修改。
当使用SLF4J Test时,Assert非常严格,并检查整个事件是否相等。在这种情况下,自定义匹配器可能很有趣:
这只检查消息是否包含文本,而不检查是否相等。因此,当消息被修改以修复错别字或给予更多细节时,如果仍然包含基本部分,则测试不会中断。
qij5mzcb3#
如果日志记录是一个业务需求,并将提供业务价值(即在发生故障时,诊断或分类问题),那么您应该将其视为任何其他需求。因此,您可能应该编写单元测试,而不是验证您的日志库是否正常工作,而是验证在预期的情况下,您的代码记录了它应该记录的内容。
更多关于此主题:https://ardalis.com/logging-and-monitoring-are-requirements
zpf6vheq4#
还有另一种方法你可以模仿LogFactory!例如:
祝你好运!
mtb9vblg5#
我肯定会考虑对日志记录场景进行单元测试。测试时,考虑在代码失败的情况下需要的信息。如果您有一个实时问题,您希望确保您有足够的信息来找到问题的原因。
避免过多的日志记录,因为在调试时,你可能看不到树木。
ecfdbz9o6#
我使用了Baeldung网站提示:https://www.baeldung.com/junit-asserting-logs
1️您有一个创建日志的类:
2️你使用copy-verbatim另一个类临时堆叠日志:
3️你在单元测试中使用它
7vux5j2d7#
我不会对只会调用您信任的库的代码进行单元测试。
你信任你的日志库吗?如果测试失败,是因为库中有bug,还是仅仅因为你没有正确配置库?你关心测试配置吗?