Search code examples
javaspring-bootjunitlogbackslf4j

How to mock static method in JUnit


In a unit test in a spring-boot environment with slf4j and logback, I want to make sure LOGGER.isTraceEnabled() returns true for a particular test class only.

The reason for that is, that sometimes we have slow and non trivial code guarded with if (LOGGER.isTraceEnabled()) {...}. In a unit test we want to make sure it does not break the application if we switch on trace.

Code under test:

public class ClassUnderTest{

    private static final Logger LOGGER = LoggerFactory.getLogger(ClassUnderTest.class);

    public void doSomething(Calendar gegenwart) {
        if (LOGGER.isTraceEnabled()) {
           // non trivial code
        }
    }
}

Test code:

public class ClassUnderTestUnitTest{

    @Test
    public void findeSnapshotMitLueke() {
        ClassUnderTest toTestInstance = new ClassUnderTest ();

        // I want to make sure trace logging is enabled, when
        // this method is executed.
        // Trace logging should not be enabled outside this
        // test class.
        toTestInstance.doSomething(Calendar.getInstance());
    }

}

Solution

  • In case you don't want to use a framework like powermock you can do the following trick:

    public class ClassUnderTest {
    
        private Supplier<Logger> loggerSupplier = () -> getLogger(ClassUnderTest.class);
    
        public void doSomething(Calendar gegenwart) {
            if (loggerSupplier.get().isTraceEnabled()) {
               // non trivial code
            }
        }
    }
    

    Now you are able to mock the logger:

    public class ClassUnderTestUnitTest{
    
        @Mock
        private Supplier<Mock> loggerSupplier;
        @Mock
        private Logger logger;
    
        @Test
        public void findeSnapshotMitLueke() {
            ClassUnderTest toTestInstance = new ClassUnderTest ();
    
            when(loggerSupplier.get()).thenReturn(logger);
            when(logger.isTraceEnabled()).thenReturn(true)
    
            toTestInstance.doSomething(Calendar.getInstance());
    
            // verifyLogger();
        }
    
    }