目标是对硬编码的 log4j Appender 进行功能测试,该 Appender 扩展了 RollingFileAppender,其中我可以使用 MyAppender 重现写入同一文件的 log4j 记录器的多个实例。我的方法是拦截 log4j 的 FileAppender 类创建的 FileOutputStream 的创建。
但是匿名应答中的 System.out 调用永远不会被调用。当我在 FileOutputStream 构造函数上放置断点时,我发现它完全按照我的预期创建,并使用了我在下面指定的参数。当我在写入方法上放置断点时,正在调用的是三个参数版本。
我使用meterware 的ServletUnit 来模拟容器中的情况。 MyLogAppender.logFile 是一个常量。
我错过了什么?
@Test
@PrepareForTest({MyLogAppender.class})
public void MyLogMessageGetsWritten() throws SAXException, IOException, Exception {
//...
// INTERCEPT LOG HERE SOMEHOW
PowerMockito.mockStatic(FileOutputStream.class);
FileOutputStream mockFos = PowerMockito.mock(FileOutputStream.class);
PowerMockito.whenNew(FileOutputStream.class).withParameterTypes(String.class, boolean.class).withArguments(MyLogAppender.logFile, true).thenReturn(mockFos);
//...
PowerMockito.doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Object mock = invocation.getMock();
System.out.println("write(byte[], int, int) Called with " + args);
return args;
}
}).when(mockFos).write(any(byte[].class), anyInt(), anyInt());
//...
// ASSERT LOG SUCCESS HERE
}
附注我正在使用 PowerMockRunner 运行,即使我没有粘贴该部分。
最佳答案
如果没有看到您的应用程序代码,就很难确定到底要建议什么。但是你可以模拟 log4j Logger 吗?只需注入(inject) Logger
的模拟并验证是否在其上调用了正确的日志方法。
如果您模拟 FileOutputStream
,那么您实际上是在测试 log4j 以及测试您自己的应用程序代码。除非您是 log4j 开发团队的成员,否则您可能不想这样做。
关于java - 当 Log4j 创建 java.io.FileOutputStream 时,如何使用 Powermockito 模拟 java.io.FileOutputStream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15362814/