1

我需要一些有关日志记录和单元测试的帮助。被测类是 Zk GenericForwardComposer,我想从测试中排除具体的日志记录和日志记录配置。我遵循一种 TDD 并且由于日志记录而导致测试失败。我已经发布了正在测试的课程和测试。我的测试没有任何 log4j 配置,因为我想要一个尽可能纯的单元测试并且尽可能简单。


测试失败:

log4j:ERROR setFile(null,true) call failed.
    java.io.FileNotFoundException: /log/t2-console.log (No such file or directory)
    at java.io.FileOutputStream.open(Native Method)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:136)
    at org.apache.log4j.FileAppender.setFile(FileAppender.java:294)
    at org.apache.log4j.RollingFileAppender.setFile(RollingFileAppender.java:207)
    at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:165)
    at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:307)
    at org.apache.log4j.xml.DOMConfigurator.parseAppender(DOMConfigurator.java:295)
    at org.apache.log4j.xml.DOMConfigurator.findAppenderByName(DOMConfigurator.java:176)
    at org. apache.log4j.xml.DOMConfigurator.findAppenderByReference(DOMConfigurator.java:191)
    at org.apache.log4j.xml.DOMConfigurator.parseChildrenOfLoggerElement(DOMConfigurator.java:523)
    at org.apache.log4j.xml.DOMConfigurator.parseCategory(DOMConfigurator.java:436)
    at org.apache.log4j.xml.DOMConfigurator.parse(DOMConfigurator.java:1004)
    at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:872)
    at org.apache.log4j.xml.DOMConfigurator.doConfigure(DOMConfigurator.java:778)
    at org.apache.log4j.helpers.OptionConverter.selectAndConfigure(OptionConverter.java:526)
    at org.apache.log4j.LogManager.<clinit>(LogManager.java:127)
    at org.apache.log4j.Logger.getLogger(Logger.java:117)
    at com.t2.integration.controller.IntegrationSearchController.<clinit>(IntegrationSearchController.java:60)
    at com.t2.integration.controller.IntegrationSearchControllerTest.doesSomeCalling(IntegrationSearchControllerTest.java:14)


我还没有为 Log4j 配置单元测试,我想遵循Red-Green-Refactor。我想我可以处理测试中的日志记录调用,但如果可能的话,我想找到一种完全排除日志记录的方法。

public class IntegrationSearchControllerTest {

    @Test
    public void doesSomeCalling() {
        IntegrationSearchController searchController = new IntegrationSearchController();
    }
}

我不希望任何 ZK 上下文或 ZK 集成测试组件泄漏到我的单元测试中。我希望测试尽可能简单。是 AOP、接口、依赖注入还是重构?

被测类:

package ...

import org.apache.log4j.Logger;

public class IntegrationSearchController extends IntegrationBaseController {

   private static final Logger LOGGER = Logger.getLogger(IntegrationSearchController.class);
...

控制器是 ZK 管理的

4

1 回答 1

2

由于您Logger是静态的(正常),您将需要使用可以模拟静态的模拟框架。这要困难得多(从框架的角度来看,因为它通常涉及操作字节码)。无论如何,它已经完成,你有选择。

下面是使用PowerMock 和 Mockito 的外观

@RunWith(PowerMockRunner.class)
@PrepareForTest(Logger.class)
public class TestIntegrationSearchController {

    @Before
    public void initMockLogger() {
        mockStatic(Logger.class);
        when(Logger.getLogger(any(Class.class))).thenReturn(mock(Logger.class));
    }

    @Test
    public void test() {
        IntegrationSearchController controller = new IntegrationSearchController();
        // controller.LOGGER is a Mockito mocked Logger
    }

}

注意:您不需要在 an 中设置模拟,@Before但我发现它更容易阅读。

现在..说了这么多,我认为您在这里解决了错误的问题。与其在每个测试中模拟日志记录,不如考虑避免这种需要的替代方法。例如,您可以将日志记录到STDOUT.

于 2013-08-15T21:00:37.747 回答