当由Log4j创建java.io.FileOutputStream时,如何使用Powermockito模拟它?
目标是对硬编码的log4j Appender进行功能测试,它扩展了RollingFileAppender,在这里我可以使用MyAppender复制log4j记录器写入同一文件的多个实例。我的方法是拦截由log4j的FileAppender类创建的FileOutputStream的创建 但是匿名答案中的System.out调用从未被调用。当我在FileOutputStream构造函数上放置一个断点时,我看到它的创建与我预期的完全一样,带有我在下面指定的参数。当我在write方法上设置断点时,调用的是三个arg版本 我使用meterware的ServletUnit来模拟容器中的情况。MyLogAppender.log文件是一个常量 我错过了什么当由Log4j创建java.io.FileOutputStream时,如何使用Powermockito模拟它?,java,junit,log4j,mockito,powermock,Java,Junit,Log4j,Mockito,Powermock,目标是对硬编码的log4j Appender进行功能测试,它扩展了RollingFileAppender,在这里我可以使用MyAppender复制log4j记录器写入同一文件的多个实例。我的方法是拦截由log4j的FileAppender类创建的FileOutputStream的创建 但是匿名答案中的System.out调用从未被调用。当我在FileOutputStream构造函数上放置一个断点时,我看到它的创建与我预期的完全一样,带有我在下面指定的参数。当我在write方法上设置断点时,调用的
@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
记录器吗?只需插入一个模拟的记录器
,并验证是否对其调用了正确的日志方法
如果您模拟FileOutputStream
,那么您实际上是在测试log4j以及您自己的应用程序代码。除非您是log4j的开发团队成员,否则您可能不想这样做。答案是:不要使用ServletUnit/HttpUnit,因为它们会妨碍您。我不知道这是静态初始化还是某些东西的私有范围,或者两者兼而有之,但当我摆脱了假容器,只是实例化了我需要的裸类时,它就起了作用。功能测试是当多个记录器从一个父容器继承所有日志时,复制日志。最初是对log4j的误解导致了重复,但是通过尝试编写测试,我现在对log4j的理解要好得多。