In many cases we want to test if our application logging is implemented in proper way. This is another easy way to testing what our application logs when we use slf4j framework.

Using slf4j-mock we can mock all logger and assert it as we do with other mocked method.

Feature of library:

  • this binding support for easy create Mockito mock for Logger
  • call to Logger can be delegated to instance of SimpleLogger, so we can create standard simplelogger.properties
  • support for testing and mocking MDC
  • light transitive dependencies - only slf4j-api and mockito-core
  • support testing in parallel in multi thread
  • all the Magic are done by Mockito plugins, so you don’t need to directly use class from this library
  • ease use

First we should add slf4j-mock binding as dependency to our project, we must remember that we can have only one slf4j binding on classpath.

<dependency>
    <groupId>org.simplify4u</groupId>
    <artifactId>slf4j-mock</artifactId>
    <version>2.0.0<version>
    <scope>test</scope>
</dependency>

Now we have class which does some logging action

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Example {

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

    public void methodWithLogDebug(String format, String args) {

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(format, args);
        }
    }

    public void methodWithLogWarn(String message) {
        LOGGER.warn(message);
        LOGGER.warn(message);
    }

    public void logError10() {
        for (int i = 0; i < 10; i++) {
            LOGGER.error("error: {}", i);
        }
    }
}

And finally we write test for it

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.slf4j.Logger;

@RunWith(MockitoJUnitRunner.class)
public class ExampleTest {

    private static final String INFO_TEST_MESSAGE = "info log test message";
    private static final String WARN_TEST_MESSAGE = "warn log test message";
    private static final String DEBUG_TEST_MESSAGE = "debug log test message";
    private static final String DEBUG_TEST_FORMAT = "Debug: {}";

    @Mock
    Logger logger;

    @InjectMocks
    private Example sut;

    @Test
    public void debugShouldNotBeLogged() {

        // given
        when(logger.isDebugEnabled()).thenReturn(false);

        // when
        sut.methodWithLogDebug(DEBUG_TEST_FORMAT, DEBUG_TEST_MESSAGE);

        // then
        verify(logger).isDebugEnabled();
        verifyNoMoreInteractions(logger);
    }

    @Test
    public void debugShouldBeLogged() {

        // given
        when(logger.isDebugEnabled()).thenReturn(true);

        // when
        sut.methodWithLogDebug(DEBUG_TEST_FORMAT, DEBUG_TEST_MESSAGE);

        // then
        verify(logger).isDebugEnabled();
        verify(logger).debug(DEBUG_TEST_FORMAT, DEBUG_TEST_MESSAGE);
        verifyNoMoreInteractions(logger);
    }

    @Test
    public void warnShouldBeLoggedTwice() {

        // when
        sut.methodWithLogWarn(WARN_TEST_MESSAGE);

        // then
        verify(logger, times(2)).warn(WARN_TEST_MESSAGE);
        verifyNoMoreInteractions(logger);
    }

    @Test
    public void errorShouldBeLogged10Times() {

        // when
        sut.logError10();

        // then
        verify(logger, times(10)).error(anyString(), any(Object.class));
        verifyNoMoreInteractions(logger);
    }
}

As we see thanks mocking slf4j logger we can prepare test for many scenario which we want.

More examples are available at project page: https://www.simplify4u.org/slf4j-mock/

In case of new requirement, bugs or other feedback we invite to github project slf4j-mock https://github.com/s4u/slf4j-mock


Tags: slf4j mock testing

Follow @Simplify4U Tweet