Checking Logging in Unit Tests

Update – I’ve written a new post here to do the same unit testing with Logback and not just Log4J

Logging is often a second class citizen in programming and one of the reasons is that logging is a pain to unit test. The simplest and most naive way of testing logging is to run a test, log to a file and then “grep” the log for the expected message. Earlier this week I stumbled across this which showed an awesomely simple way to unit test logging. I wrote up a simple version that takes advantage of some of the syntactical sugar of the Mockito framework that runs out of the box for my current team. So here it is.

package com.bloodredsun;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

 * @author Martin Anderson
 * based on example from
public class ExampleThatLogs {

    private static final Log LOG =

    public String concat(String a, String b) {"String a:" + a + ", String b:" + b);
        return a+b;
package com.bloodredsun;

import org.apache.log4j.Appender;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.spi.LoggingEvent;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.verify;

 * @author Martin Anderson
public class ExampleThatLogsTest {

    private Appender mockAppender;
    private ArgumentCaptor captorLoggingEvent;

    public void setup() {

    public void teardown() {

    public void shouldConcatAndLog() {
        ExampleThatLogs example = new ExampleThatLogs();
        String result = example.concat("foo", "bar");
        assertEquals("foobar", result);

        LoggingEvent loggingEvent = captorLoggingEvent.getValue();
        //Check log level
        assertThat(loggingEvent.getLevel(), is(Level.INFO));
        //Check the message being logged
            is("String a:foo, String b:bar"));

7 thoughts on “Checking Logging in Unit Tests

  1. Pingback: Use JMockit to Unit test logging output | T. C. Mits

  2. AgileBitFlipper

    In the setup() method, aren’t you missing a call to instantiate the mockAppender just before the addAppender() call?

    mockAppender = mock(Appender.class);

    1. admin

      Nope. The annotations @RunWith(MockitoJUnitRunner.class) and @Mock take care of that for you and get rid of all those verbose mock(clazz.class) calls.

  3. Shilan

    thanks for the post. I was wondering how it will work for slf4j logger? It seems that it doesn’t work for that.

  4. Warden

    Thank you so much for this example. You really helped me out! I only had to make one change from:
    private ArgumentCaptor captorLoggingEvent;
    private ArgumentCaptor captorLoggingEvent;

  5. Pingback: java - Junit test du journal des ├ętats

  6. Anshul

    This throws error if we have multiple logs in our method while capturing the Event. How can we resolve that?


Leave a Reply to Shilan Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.