0

In a Spring Boot application I'm using the following logback configuration in logback-spring.xml.

Depending on the Spring property app.json-logging the application shall either use the default CONSOLE appender or the custom CONSOLE_JSON appender which writes log messages in JSON.

While the configuration is working, I'm having trouble writing a test for this behavior. Please see the below test class.

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!-- https://docs.spring.io/spring-boot/docs/2.7.x/reference/html/howto.html#howto.logging.logback -->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>

    <springProperty scope="context" name="jsonLogging" source="app.json-logging"/>
  
    <appender name="CONSOLE_JSON" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
    </appender>

    <root level="INFO">
        <if condition='property("jsonLogging").equals("true")'>
            <then>
                <appender-ref ref="CONSOLE_JSON"/>
            </then>
            <else>
                <appender-ref ref="CONSOLE"/>
                <appender-ref ref="GELF"/>
            </else>
        </if>
    </root>

</configuration>

The test class...

@ActiveProfiles("json-logging")
public class LoggingIT extends AbstractIntegrationTest {

    private final PrintStream originalSystemOut = System.out;
    private final ByteArrayOutputStream logCapturingStream = new ByteArrayOutputStream();

    @BeforeEach
    void beforeEach() {
        System.setOut(new PrintStream(logCapturingStream));
    }

    @AfterEach
    void afterEach() {
        System.setOut(originalSystemOut);
    }

    @Test
    public void shouldLogMessagesInJsonFormat() throws JSONException {
        final Logger logger = LoggerFactory.getLogger(LoggingIT.class);

        logger.info("Test log message");

        String capturedLog = logCapturingStream.toString();
        final JSONObject jsonLog = new JSONObject(capturedLog);

        assertThat(jsonLog.get("message").toString()).isEqualTo("Test log message");
    }
}

The test passes when running it on its own. It fails, however, when running it along with the other integration tests, e.g. in mvn verify. The assertion fails because the test then does not use CONSOLE_JSON but CONSOLE, so it seems as if the logger is not "re-initialized" for this test class.

I already tried adding @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) but it does not work either.

Robert Strauch
  • 12,055
  • 24
  • 120
  • 192

0 Answers0