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:
Mockito
mock for Logger
Logger
can be delegated to instance of SimpleLogger
,
so we can create standard simplelogger.properties
MDC
slf4j-api
and mockito-core
Mockito
plugins, so you don’t need to directly use class from this libraryFirst 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