Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Unit testing logback based logging statements
package com.brs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Simple class that we use to trigger a log statement.
*/
public class ExampleThatLogs {
private static final Logger LOG = LoggerFactory.getLogger(ExampleThatLogs.class);
public String concat(String a, String b) {
LOG.info("String a:" + a + ", String b:" + b);
return a+b;
}
}
package com.brs;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.slf4j.LoggerFactory;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.verify;
/**
* Our Test class shows how we can hook into logback with mockito to see the
* logging activity
*/
@RunWith(MockitoJUnitRunner.class)
public class ExampleThatLogsTest {
@Mock
private Appender mockAppender;
//Captor is genericised with ch.qos.logback.classic.spi.LoggingEvent
@Captor
private ArgumentCaptor<LoggingEvent> captorLoggingEvent;
//I've cheated a little here and added the mockAppender to the root logger
//It's not quite necessary but it also shows you how it can be done
@Before
public void setup() {
final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
logger.addAppender(mockAppender);
}
//Always have this teardown otherwise we can stuff up our expectations. Besides, it's
//good coding practise
@After
public void teardown() {
final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
logger.detachAppender(mockAppender);
}
@Test
public void shouldConcatAndLog() {
//given
ExampleThatLogs example = new ExampleThatLogs();
//when
final String result = example.concat("foo", "bar");
//then
assertEquals("foobar", result);
//Now verify our logging interactions
verify(mockAppender).doAppend(captorLoggingEvent.capture());
//Having a genricised captor means we don't need to cast
final LoggingEvent loggingEvent = captorLoggingEvent.getValue();
//Check log level is correct
assertThat(loggingEvent.getLevel(), is(Level.INFO));
//Check the message being logged is correct
assertThat(loggingEvent.getFormattedMessage(),
is("String a:foo, String b:bar"));
}
}
@coryellenberger

This comment has been minimized.

Show comment
Hide comment

Very helpful

@klassounski-daitan

This comment has been minimized.

Show comment
Hide comment
@klassounski-daitan

klassounski-daitan Jun 30, 2016

Could you show me the pom please? I'm having a problem and probably because of the packages versions.
I'm getting:

Wanted but not invoked:
mockAppender.doAppend();
-> at com.br.ExampleThatLogsTest.shouldConcatAndLog(ExampleThatLogsTest.java:61)
Actually, there were zero interactions with this mock.

Could you show me the pom please? I'm having a problem and probably because of the packages versions.
I'm getting:

Wanted but not invoked:
mockAppender.doAppend();
-> at com.br.ExampleThatLogsTest.shouldConcatAndLog(ExampleThatLogsTest.java:61)
Actually, there were zero interactions with this mock.

@birqan

This comment has been minimized.

Show comment
Hide comment
@birqan

birqan May 24, 2017

A big and fat THANK YOU for your share. Thumbs up!

birqan commented May 24, 2017

A big and fat THANK YOU for your share. Thumbs up!

@m9abbas

This comment has been minimized.

Show comment
Hide comment
@m9abbas

m9abbas Dec 14, 2017

Very Helpful! Thank You!

m9abbas commented Dec 14, 2017

Very Helpful! Thank You!

@mallesh-np

This comment has been minimized.

Show comment
Hide comment
@mallesh-np

mallesh-np Mar 5, 2018

Can you please share your logback.xml?

Can you please share your logback.xml?

@nvlinh

This comment has been minimized.

Show comment
Hide comment
@nvlinh

nvlinh May 21, 2018

I use @RunWith(SpringJUnit4ClassRunner.class) for run it, but not work, please tell me the way use it with @RunWith(SpringJUnit4ClassRunner.class)

nvlinh commented May 21, 2018

I use @RunWith(SpringJUnit4ClassRunner.class) for run it, but not work, please tell me the way use it with @RunWith(SpringJUnit4ClassRunner.class)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment