Search code examples
spring-bootspring-boot-test

Spring Boot JUnit cannot reset logging context between test classes


In my Spring Boot project, I have test classes where I'm checking for log messages using ListAppender, and they've been working fine. These are like:

@ExtendWith(MockitoExtension.class)
class MyServiceTest {
    ...
}

My problem arose when I tried to check a Level.TRACE message. We use logback, and it is configured in the main app only down to DEBUG level, so I added a logback-test.xml to my test context to set the logging level to TRACE. All is fine when I run my test class on its own, and I get nice log messages like

21:31:18.332 [main] TRACE a.b.c.MyService - Processing Started: File ...

I also have tests that run under the Spring Boot context, like

@SpringBootTest
@RunWith(SpringRunner.class)
public class RedisServiceTest {
    ...
}

This type of test causes logback to use the main logging config, and I get log output like

{"timestamp":"2024-07-26T08:32:56.172-07:00","logger":"a.b.c.RedisService","level":"INFO","thread":"[main]","message":"Caching file size in redis with hashKey: ..."}

Where it breaks down is when I run the entire test suite. When my SpringBootTest runs before my plain Mockito test, the logger gets stuck with the non-test logging config, and my TRACE messages do not get logged, so my tests fail. I've tried to use the @DirtiesContext annotation on my SpringBootTest class, but that does not solve the issue. If I delete my SpringBootTest class, the test suite runs fine. How can I reset my logging context?

Additional config info:

  • Spring Boot 2.3.12
  • JUnit 5.6.3
  • Logback 1.2.3

Solution

  • Ok, I figured out my problem. I never should have added logback-test.xml into the test resources. I removed that file and modified the main logback config file by adding

    <springProfile name="test">
        <logger name="com.mycompany.myproject" level="trace"/>
    </springProfile>
    

    and all is well.

    Edit: I had to reinstate logback-test.xml in order to run the test class on its own (not as part of the suite). Since my test does not involve running Spring in a VM, my main logback.xml is never incorporated, and thus I need a logback config file in my test context. If I run the whole test suite, then by chance the VM-based test(s) may run before this class, whereupon the test logback config gets replaced by the main logback config. ¯\_(ツ)_/¯

    tl;dr -- do add a logback-test.xml containing the trace level, and also modify the main logback.xml to set the project package (or whatever is needed) level to trace.