Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当由Log4j创建java.io.FileOutputStream时,如何使用Powermockito模拟它?_Java_Junit_Log4j_Mockito_Powermock - Fatal编程技术网

当由Log4j创建java.io.FileOutputStream时,如何使用Powermockito模拟它?

当由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方法上设置断点时,调用的

目标是对硬编码的log4j Appender进行功能测试,它扩展了RollingFileAppender,在这里我可以使用MyAppender复制log4j记录器写入同一文件的多个实例。我的方法是拦截由log4j的FileAppender类创建的FileOutputStream的创建

但是匿名答案中的System.out调用从未被调用。当我在FileOutputStream构造函数上放置一个断点时,我看到它的创建与我预期的完全一样,带有我在下面指定的参数。当我在write方法上设置断点时,调用的是三个arg版本

我使用meterware的ServletUnit来模拟容器中的情况。MyLogAppender.log文件是一个常量

我错过了什么

@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的理解要好得多。