Logger.getRootLogger().addAppender(appender) removed in Test cases

Viewed 232

I am migrating all old legacy Log4j1.x Test cases to Log4j2.x based test cases, I've a test case like below, which I am not able to convert, condition is I dont want to change anything in asserts.

Note: I can't use Junit 5, because its legacy code, is there any way we can still use log4j 2.x with the Junit 4 and try to fix the original issues?

Need solution.

@Mock 
AppenderSkeleton appender;
@Captor 
ArgumentCaptor<LoggingEvent> logCaptor;

@Test
public void testHeaderFooterValidationWithHeaderFooterInfoDisabled() {
    Logger.getRootLogger().addAppender(appender);
    
    
    //Turn off header and footer read
    testLoader.setEnableHeaderInfo(false);
    testLoader.setEnableTrailerInfo(false);
    
    //Turn on header footer validation
    testLoader.setValidateHeader(true);
    verify(appender, times(1)).doAppend(logCaptor.capture());
    assertEquals("Warning message should have been logged", "Some Message", logCaptor.getValue().getRenderedMessage());
    
    testLoader.setValidateTrailer(true);
    verify(appender, times(2)).doAppend(logCaptor.capture());
    assertEquals("Warning message should have been logged", "Some Message", logCaptor.getValue().getRenderedMessage());
    
    testLoader.processEvent(paramsMap);
    
    assertThat(configRegion.values()).contains("AAAA,BBBB,CCCC");
    assertThat(configRegion.keySet()).contains("abc.config.property");
}

I tried to replace

Logger.getRootLogger().addAppender(appender);

To

ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
RootLoggerComponentBuilder rootLogger  = builder.newRootLogger(Level.ERROR);
rootLogger.add(builder.newAppenderRef("stdout"));
builder.add(rootLogger);
1 Answers

In Log4j2 you have a ListAppender in the tests JAR.

Combined with the LoggerContextSource JUnit 5 extension it allows you to inject a ListAppender in your test. E.g.:

@Test
@LoggerContextSource("log4j2-test.xml")
public void testHeaderFooterValidationWithHeaderFooterInfoDisabled(@Named("List") Appender appender) {
   ...
}

and a log4j2-test.xml file:

<Configuration>
  <Appenders>
    <List name="List" />
  </Appenders>
  <Loggers>
    <Root level="DEBUG">
      <AppenderRef ref="List" />
    </Root>
  </Loggers>
</Configuration>

If you run the test classes in parallel, there is a recent thread on the log4j-user mailing list.

Edit: If you use JUnit 4, you can use the LoggerContextRule:

@Rule
public final LoggerContextRule rule = new LoggerContextRule();

@Test
public void testHeaderFooterValidationWithHeaderFooterInfoDisabled() {
    final ListAppender appender = rule.getAppender("List");

    ...
    // Snapshot of messages
    final List<LogEvent> events = appender.getEvents();
    assertEquals(1, events.size());
    assertEquals("Some Message", events.get(0).getMessage().getFormattedMessage());
    appender.clear();
}
Related