2013-03-12 108 views
0

目标是对一个硬编码的log4j Appender进行功能测试,该测试扩展了RollingFileAppender,我可以在其中重现使用MyAppender写入同一文件的log4j记录器的多个实例。我的方法是拦截由log4j的FileAppender类创建的FileOutputStream的创建。如何通过Log4j创建Powermockito模拟java.io.FileOutputStream?

但匿名答案中的System.out调用永远不会被调用。当我在FileOutputStream构造函数上放置一个断点时,我发现它正在按照我的预期完全创建,并使用下面指定的参数。当我在写入方法上放置一个断点时,它是被调用的三个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 

} 

P.S.即使我没有粘贴该部分,我仍在使用PowerMockRunner。

回答

0

没有看到您的应用程序代码,很难确切地确定要建议的内容。但是,你可以嘲笑log4j Logger?只需注入Logger的模拟并验证正确的日志方法正在被调用。

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

+0

功能测试是在多个记录器从一个容器中的父容器继承时重现日志重复。这是log4j的误解,首先导致了重复,但通过尝试编写测试,我明白log4j现在好多了。 – bickelj 2013-03-26 14:11:22

0

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