我有一些被测代码调用 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,但假设这是可能的。)
非常感谢这些(令人惊讶的)快速而有用的答案;他们让我走上了解决问题的正确道路。
代码库是我想使用它,使用 java.util.logging 作为它的记录器机制,而且我对这些代码感觉不够熟悉,无法将其完全更改为 log4j 或记录器接口/外观。但是基于这些建议,我“破解”了一个 julhandler 扩展,这是一种享受。
下面是一个简短的总结。扩展java.util.logging.Handler:
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,或者将它们全部推送到堆栈中,直到溢出。
LogRecord
在准备 junit-test 时,您创建一个java.util.logging.Logger并添加这样一个新LogHandler的:
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:
setUseParentHandlers()
libraryUnderTest.setLogger(logger); methodUnderTest(true); // see original question. assertEquals("Log level as expected?", Level.INFO, handler.checkLevel() ); }
(当然,您会将大部分工作转移到@Before方法中并进行各种其他改进,但这会使演示文稿变得混乱。)
@Before