如何测试Spring Boot组件中包含的log4j2自定义记录器

时间:2018-03-23 07:44:32

标签: java spring-boot log4j2

我有一个包含静态自定义记录器的Spring Boot @Component,我需要测试该组件内部生成的日志消息。这是组件:

@Component
public class CustomComponent {

  private static CustomLogger logger = CustomLogger.getLogger(CustomComponent.class);

  public void setLogger(CustomLogger logger) {
    CustomComponent.logger = logger;
  }

  public void doSomething(){
    logger.info("This is a test from CustomComponent");
  }

}

这是CustomLogger(这个代码很简单。实际上我们需要一个自定义记录器,因为我们需要在其中做其他事情,但它们与这个问题无关):

public class CustomLogger {

  private final ExtendedLoggerWrapper log;

  private CustomLogger(final Logger log) {
    this.log = new ExtendedLoggerWrapper((AbstractLogger) log, log.getName(), log.getMessageFactory());
  }

  public static synchronized CustomLogger getLogger(final Class<?> clazz) {
      final Logger wrapped = LogManager.getLogger(clazz);
      return new CustomLogger(wrapped);
  }

  public void info(Object message) {
    if (log.isInfoEnabled()) {
      log.info(message);
    }
  }
}

log4j2.xml配置

这是log4j2文件:

<Configuration status="warn" name="CustomLogger" packages="">

  <Appenders>
    <List name="List1" />
    <Console name="APPLICATION" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{ISO8601} %5p %m (%F:%L)%n"/>
      <Filters>
        <!-- This allows DEBUG, INFO, WARN, ERROR AND FATAL -->
        <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
      </Filters>
    </Console>

  </Appenders>

  <Loggers>
    <Logger name="com.example.demo" level="DEBUG" additivity="false">
      <AppenderRef ref="APPLICATION"/>
    </Logger>

    <Root level="WARN">
      <AppenderRef ref="APPLICATION"/>
      <AppenderRef ref="List1" />
    </Root>
  </Loggers>

</Configuration>

JUnit配置

在我的JUnit类中,我有@Autowired组件,我使用ListAppender检索了LoggerContextRule。在setup()我创建了mockLogger,我使用setter传递给CustomComponent。  这是我的JUnit测试的代码:

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {

  @Autowired
  CustomComponent component;

  @ClassRule
  public static LoggerContextRule context = new LoggerContextRule("log4j2.xml");
  private ListAppender listAppender;


  @Before
  public void setup(){
    CustomLogger mockLogger = CustomLogger.getLogger(this.getClass());
    component.setLogger(logger);
    listAppender = context.getListAppender("List1").clear();
  }

    @Test
    public void testCustomComponent() {
      component.doSomething();
    final List<LogEvent> events = listAppender.getEvents();
    assertThat(events, hasSize(1));
    }
}

我希望listAppender能够记录mockLogger中的事件,但是它是空的并且测试失败了:

java.lang.AssertionError: 
Expected: a collection with size <1>
     but: collection size was <0>

我不明白我在做什么错误,这是否是上下文的问题 - 在JUnit类和@Component中可能有所不同 - 或其他。

我花了很多时间尝试阅读log4j2的官方文档,或尝试在Stackoverflow上找到类似的问题,但没有成功。

更新

找到解决方案。有时只是写下你的问题并试图总结它,你就会得到顿悟。我忘了在正确的记录器中添加<AppenderRef ref="List1">。它只在根记录器中设置,这就是它无法正常工作的原因。

0 个答案:

没有答案