3

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);
Jeff Cook
  • 7,956
  • 36
  • 115
  • 186
  • Did you check the related question links https://stackoverflow.com/questions/59713891/appenderskeleton-log4j2 ? Do you need to move all output to console? – Ori Marko Jun 14 '22 at 07:12

1 Answers1

1

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();
}
Piotr P. Karwasz
  • 12,857
  • 3
  • 20
  • 43
  • hey, Thanks, I cant 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? – Jeff Cook Jun 10 '22 at 07:16
  • There is also a JUnit 4 version of the extension mentioned above: [`LoggerContextRule`](https://github.com/apache/logging-log4j2/blob/release-2.x/log4j-core/src/test/java/org/apache/logging/log4j/junit/LoggerContextRule.java). – Piotr P. Karwasz Jun 10 '22 at 08:25
  • Hey, Thanks, I see issue here at `verify(appender, times(1)).doAppend(logCaptor.capture());`, but I don't see how can we fix it ? – Jeff Cook Jun 13 '22 at 12:24
  • The above solution not working for me, getting `java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=(org.apache.logging.log4j.core.Appender)]` – Jeff Cook Jun 13 '22 at 13:44
  • @JeffCook: I added an example for JUnit 4. As the JUnit 5 example, this requires `log4j-core` with a `tests` classifier. – Piotr P. Karwasz Jun 15 '22 at 16:32
  • 1
    Both Named and LoggerContextSource come from `log4j-core` `test-jar`. If you use Maven, attach it as follows: `test-jar` – Egor Nepomnyaschih Jun 23 '22 at 14:24