1

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

但是匿名 Answers 中的 System.out 调用永远不会被调用。当我在 FileOutputStream 构造函数上放置一个断点时,我看到它的创建完全符合我的预期,我在下面指定了参数。当我在 write 方法上设置断点时,调用的是三个 arg 版本。

我正在使用 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

}

PS 即使我没有粘贴那部分,我也正在使用 PowerMockRunner 运行。

4

2 回答 2

0

如果没有看到您的应用程序代码,就很难确切地确定要建议什么。但是你可以模拟 log4jLogger吗?只需注入一个模拟Logger并验证是否在其上调用了正确的日志方法。

如果您FileOutputStream改为模拟,那么您实际上是在测试 log4j 以及测试您自己的应用程序代码。除非您在 log4j 的开发团队中,否则您可能不想这样做。

于 2013-03-16T22:24:45.357 回答
0

答案:消除 ServletUnit/HttpUnit 的使用,因为它们妨碍了它们。我不知道它是静态初始化还是某些东西的私有范围或两者兼而有之,但是当我摆脱假容器并实例化我需要的裸类时,它就起作用了。

于 2013-03-26T14:14:10.870 回答