【发布时间】:2013-08-12 11:18:50
【问题描述】:
我正在编写一个测试,我想捕获测试方法在 STDOUT 上发送的消息。这是我的代码:
@Test
public void testAction() throws IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException,
CmdLineException, IOException {
PrintStream originalSTDOUT = System.out;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
try {
System.setOut(ps);
// Call to the method that will print text to STDOUT...
ps.flush();
String batchLog = baos.toString("UTF-8");
assertTrue("Invalid exception text !", batchLog.contains("my expected text..."));
} finally {
System.setOut(originalSTDOUT);//Restore original STDOUT
originalSTDOUT.write(baos.toByteArray());// Write back to STDOUT, even if I comment this line, outputs go to STDOUT...
ps.close();
}
}
不幸的是,batchLog 始终为空,尽管我仍然可以将预期的文本读取到 STDOUT。
将文本打印到 STDOUT 的方法实际上捕获了一个异常。然后它将它传递给Logger,如下所示:
log.warn("发生错误:", e);
e 是我在测试中调用的方法中引发的异常。
Logger 使用此附加程序打印其消息:org.apache.log4j.ConsoleAppender。此附加程序没有应用特殊配置。
我错过了什么?
附:
这个SO answer 很有趣,但它对我不起作用,因为在StandardOutputStreamLog rule 可以行动之前已经创建了ConsoleAppender。
Java 6
Junit 4.10
【问题讨论】:
-
方法如何打印文本?
System.setOut只改变System.out字段的值;它可能使用该字段的缓存值或使用其他方式写入标准输出。 -
代码作为独立的主要方法工作正常。检查您的 JUnit 设置和拆卸方法。问题出在其他地方。
-
不能用普通的 System.out.println(...) 重现这个,你如何将文本打印到标准输出?
-
@Joni 我已经更新了我的帖子,添加了该方法如何将文本打印到标准输出。
-
既然您使用的是 Log4J,您就不能更改日志配置吗?
ConsoleAppender类使用创建 appender 时System.out的任何值;当您的测试执行时,更改它为时已晚。见源:docjar.com/html/api/org/apache/log4j/ConsoleAppender.java.html
标签: java redirect junit stdout junit4