小编典典

如何对记录器中的消息执行 JUnit 断言

all

我有一些被测代码调用 Java 记录器来报告其状态。在 JUnit 测试代码中,我想验证是否在此记录器中创建了正确的日志条目。大致如下:

methodUnderTest(bool x){
    if(x)
        logger.info("x happened")
}

@Test tester(){
    // perhaps setup a logger first.
    methodUnderTest(true);
    assertXXXXXX(loggedLevel(),Level.INFO);
}

我想这可以用一个特别适应的记录器(或处理程序,或格式化程序)来完成,但我更愿意重新使用已经存在的解决方案。(而且,老实说,我不清楚如何从记录器获取
logRecord,但假设这是可能的。)


阅读 77

收藏
2022-05-17

共1个答案

小编典典

非常感谢这些(令人惊讶的)快速而有用的答案;他们让我走上了解决问题的正确道路。

代码库是我想使用它,使用 java.util.logging 作为它的记录器机制,而且我对这些代码感觉不够熟悉,无法将其完全更改为 log4j
或记录器接口/外观。但是基于这些建议,我“破解”了一个 julhandler 扩展,这是一种享受。

下面是一个简短的总结。扩展java.util.logging.Handler

class LogHandler extends Handler
{
    Level lastLevel = Level.FINEST;

    public Level  checkLevel() {
        return lastLevel;
    }

    public void publish(LogRecord record) {
        lastLevel = record.getLevel();
    }

    public void close(){}
    public void flush(){}
}

显然,您可以从 中存储您喜欢/想要/需要的任意数量LogRecord,或者将它们全部推送到堆栈中,直到溢出。

在准备 junit-test 时,您创建一个java.util.logging.Logger并添加这样一个新LogHandler的:

@Test tester() {
    Logger logger = Logger.getLogger("my junit-test logger");
    LogHandler handler = new LogHandler();
    handler.setLevel(Level.ALL);
    logger.setUseParentHandlers(false);
    logger.addHandler(handler);
    logger.setLevel(Level.ALL);

调用setUseParentHandlers()是使正常处理程序静音,以便(对于此 junit-test
运行)不会发生不必要的日志记录。做任何你的被测代码需要使用这个记录器,运行测试和 assertEquality:

    libraryUnderTest.setLogger(logger);
    methodUnderTest(true);  // see original question.
    assertEquals("Log level as expected?", Level.INFO, handler.checkLevel() );
}

(当然,您会将大部分工作转移到@Before方法中并进行各种其他改进,但这会使演示文稿变得混乱。)

2022-05-17