java - 如何对日志上的消息进行单元测试?

标签 java unit-testing logging junit

我有一些正在测试的代码,它们调用 Java 记录器来报告其状态。在 JUnit 测试代码中,我想确认在此记录器中创建了正确的日志条目。例如;我有两个针对两个不同条件的错误日志。

methodGoingToBeTested(bool a, bool b){
    if(a)
        logger.info("a happened")
    else()
        logger.info("b happened")

}

@Test tester(){

    methodGoingToBeTested(true);
    assertXXXXXX(loggedLevel(),Level.INFO);
}

我想测试一下我在实际方法中所遇到的记录器错误是否在其应生成的条件下准确生成。我在网上查过,但建议确实很旧。有没有人有什么建议?感谢您的帮助。

我知道这里有一篇类似的帖子,但该帖子确实已经过时了,现在无法使用相同的过程来解决这个问题,这就是我首先问这个问题的原因。

最佳答案

您无法测试这一点的原因可能是因为您在正在测试的类中实例化了记录器。

class MyClass
{
    private final Logger logger = /* whatever */;
}

如果您使用 dependency injection您将允许自己测试此行为。

class MyClass
{
    private final Logger logger;

    MyClass(final Logger logger)
    {
        this.logger = logger;
    }
}

现在,在您的测试中,您注入(inject)一个模拟或假记录器。这是一个使用 Mockito 的简单示例:

@Mock
Logger logger;

@Test
void tester()
{
    MyClass inst = new MyClass(logger);

    methodUnderTest(true);

    BDDMockito.verify(logger).info(Mockito.anyString());
}

如果您愿意,您可以执行更严格的验证。

同样,您可以出于测试目的创建一个假 Logger 实现,该实现执行所需的断言,而不是模拟。这是一个非常基本的示例:

class FakeLogger implements Logger
{
    private boolean hasInfoBeenCalled = false;

    @Override
    public void info(String message)
    {
        hasInfoBeenCalled = true;
    }

    // Other Logger methods...

    public boolean hasInfoBeenCalled()
    {
        return hasInfoBeenCalled;
    }
}

@Test
void tester()
{
    FakeLogger logger = new FakeLogger();
    MyClass inst = new MyClass(logger);

    methodUnderTest(true);

    Assert.assertTrue(logger.hasInfoBeenCalled());
}
<小时/> 话虽这么说,如果唯一可观察和可测试的行为是写入日志文件,我会仔细重新考虑您的类的设计。如果您决定将来更改日志记录,您很可能会发现您的测试非常脆弱。

关于java - 如何对日志上的消息进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47772091/

相关文章:

spring - @Autowired 不应该在没有 @RunWith(SpringRunner.class) 的情况下工作,但可以

javascript - 如何在 RequireJS 中模拟单元测试的依赖项?

powershell - 将日志记录快速添加到现有的 powershell 脚本集

java - 三个按钮问题

java - 使用脚本从 *.jar 中删除文件

java - 使用 XYDataset(JFreeChart) 添加双变量值到 XySeries

java - 我的 GlassFish 服务器,部署,null,false

unit-testing - 如何在带有 Jest 的 react-native 中使用模拟的 fetch() 对 API 调用进行单元测试

ruby - Rack 请求日志

asp.net-mvc - 有没有办法为每个 Controller 方法添加虚拟方法行为? (即记录)