Search code examples
javaspring-bootlog4j2

How can I unit test whether my app logs as expected with log4j2?


I tried using reflection, but in my case sl4fj creates a final logger. This means I can't customize it.

Any advice?


Solution

  • if you're using log4j2 with spring-boot, you can do the following:

    test code:

    import org.springframework.boot.test.system.CapturedOutput;
    import org.springframework.boot.test.system.OutputCaptureExtension;
    import static org.assertj.core.api.Assertions.assertThat;
    
    @ExtendWith(OutputCaptureExtension.class)
     class MyClassTest {
        @Test
        void myFunction_whenIDoAThing_thenItDoesNotLog(CapturedOutput output) {
            // given
    
            ...
            // when
            when(myDependency.doSomething()).thenReturn(something);
    
            myClass.doSomething();
    
            // then
            assertThat(output).doesNotContain(AN_EXPECTED_ERROR_MESSAGE);
    
            verify(myDependency).doSomething();
        }
    }
    

    the key is adding the follow attribute and sending the logs to system out

    https://docs.spring.io/spring-boot/api/java/org/springframework/boot/test/system/OutputCaptureExtension.html https://logging.apache.org/log4j/2.x/manual/appenders.html#ConsoleAppender

    log4j2 configuration:

    ❯ cat spring-rest/src/test/resources/log4j2-test.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn">
      <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT" follow="true">
          <PatternLayout pattern="%m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Root level="warn">
          <AppenderRef ref="STDOUT"/>
        </Root>
      </Loggers>
    </Configuration>