首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我们应该对日志进行单元测试吗?

我们应该对日志进行单元测试吗?
EN

Stack Overflow用户
提问于 2012-08-17 09:34:27
回答 4查看 25.8K关注 0票数 34

通常可以在代码中看到日志记录功能:

代码语言:javascript
复制
public class A {

    private static final Log LOG = LogFactory.getLog(A.class);

和用法:

代码语言:javascript
复制
} catch (Exception e) {
    LOG.error(e.getMessage(), e);
    throw e;
}

但是我从来没有见过这样的代码的单元测试。

当然,我会测试抛出异常和异常类型,但我应该编写测试来检查日志记录信息吗?我倾向于认为日志记录是系统行为的另一部分,因此从逻辑上讲,应该退出测试以涵盖它。

假设我应该介绍它,这意味着我应该更改我的原始代码以注入模拟日志,并检查"error“方法是用预期的消息调用的。但是,如果我的原始类是service,并且它是由spring实例化的,我应该注入一些记录器以及其他依赖项吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-08-17 09:51:10

测试日志库不是由您决定的。但是,当抛出异常时,您的类会在正确的级别记录一条消息,这是值得测试的。您正在测试的是您的代码是否正确地使用了日志库。

要使上面的代码可测试,请使用依赖项注入。这里假设记录器实现了一个接口ILog。您可以将记录器作为构造函数参数传递给类A。然后,测试代码将创建ILog的模拟实现,并将其传递给构造函数。上面的代码中没有显示异常是如何发生的,但它可能是通过其他依赖对象来实现的。所以你也嘲笑它,并让它抛出一个异常。然后检查模拟ILog是否调用了error方法。也许你想检查它记录的消息,但这可能太过分了,因为它使测试代码变得脆弱。

票数 18
EN

Stack Overflow用户

发布于 2017-04-24 17:07:32

是的,当日志正在做一些需要做的事情时,我们应该测试日志。例如,您在一些外部应用程序中有钩子,这些应用程序会扫描日志中的某些事件。在这种情况下,您肯定希望确保完成日志记录。

当然,您不会想要测试每个日志记录事件,我认为大多数情况下应该只测试错误(而不是所有错误)。

使用SLF4j等现代日志记录框架,您可以简单地注入一个自定义处理程序,该处理程序将的事件存储在内存中,并可在以后针对该事件进行断言。

我现在想到的有两个:

SLF4JTesting:不需要修改日志配置,但需要注入日志工厂,这可能会导致代码修改。

SLF4J Test:不像slf4jtesting那样强大,而且似乎不是开发出来的,但可以很好地与现有代码一起工作。除了用于测试的记录器配置外,没有任何修改。

使用SLF4J测试时,断言非常严格,并检查整个事件是否相等。在这种情况下,自定义匹配器可能很有趣:

代码语言:javascript
复制
public static Matcher<LoggingEvent> errorMessageContains(final String s) {
    return new TypeSafeMatcher<LoggingEvent>() {
        @Override
        public void describeTo(final Description description) {
            description.appendText(" type " + Level.ERROR + " should contain ")
                    .appendValue(s);
        }

        @Override
        protected void describeMismatchSafely(final LoggingEvent item, final Description mismatchDescription) {
            mismatchDescription.appendText(" was type ").appendValue(l)
                    .appendText(" message ").appendValue(item.getMessage());
        }

        @Override
        protected boolean matchesSafely(final LoggingEvent item) {
            return item.getLevel().equals(Level.ERROR)
                    && item.getMessage().contains(s);
        }
    };
}

这只检查消息是否包含文本,而不检查它是否相等。因此,当消息被修改以修复拼写错误或提供更多细节时,如果基本部分仍然包含,则测试不会中断。

票数 6
EN

Stack Overflow用户

发布于 2017-08-10 20:32:35

如果日志记录是一项业务需求,并且将提供业务价值(例如,在发生故障时用于诊断或分类问题),那么您应该将其视为任何其他需求。因此,您可能应该编写单元测试,而不是验证您的日志库是否正常工作,而是验证在预期的情况下,您的代码是否记录了它应该记录的内容。

有关此主题的更多信息:https://ardalis.com/logging-and-monitoring-are-requirements

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11998713

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档