Intellipaat Back

Explore Courses Blog Tutorials Interview Questions
0 votes
3 views
in Java by (10.2k points)

I have some code-under-test that calls on a Java logger to report its status. In the JUnit test code, I would like to verify that the correct log entry was made in this logger. Something along the following lines:

methodUnderTest(bool x){

    if(x)

        logger.info("x happened")

}

@Test tester(){

    // perhaps setup a logger first.

    methodUnderTest(true);

    assertXXXXXX(loggedLevel(),Level.INFO);

}

I suppose that this could be done with a specially adapted logger (or handler, or formatter), but I would prefer to re-use a solution that already exists. (And, to be honest, it is not clear to me how to get at the logRecord from a logger, but suppose that that's possible.)

2 Answers

0 votes
by (46k points)

I've needed this several times as well. I've put together a small sample below, which you'd want to adjust to your needs. Basically, you create your own Appender and add it to the logger you want. If you'd want to collect everything, the root logger is a good place to start, but you can use a more specific if you'd like. Don't forget to remove the Appender when you're done, otherwise you might create a memory leak. Below I've done it within the test, but setUp or @Before and tearDown or @After might be better places, depending on your needs.

Also, the implementation below collects everything in a List in memory. If you're logging a lot you might consider adding a filter to drop boring entries, or to write the log to a temporary file on disk (Hint: LoggingEvent is Serializable, so you should be able to just serialize the event objects, if your log message is.)

import org.apache.log4j.AppenderSkeleton;

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

import org.apache.log4j.spi.LoggingEvent;

import org.junit.Test;

import java.util.ArrayList;

import java.util.List;

import static org.hamcrest.CoreMatchers.is;

import static org.junit.Assert.assertThat;

public class MyTest {

    @Test

    public void test() {

        final TestAppender appender = new TestAppender();

        final Logger logger = Logger.getRootLogger();

        logger.addAppender(appender);

        try {

            Logger.getLogger(MyTest.class).info("Test");

        }

        finally {

            logger.removeAppender(appender);

        }

        final List<LoggingEvent> log = appender.getLog();

        final LoggingEvent firstLogEntry = log.get(0);

        assertThat(firstLogEntry.getLevel(), is(Level.INFO));

        assertThat((String) firstLogEntry.getMessage(), is("Test"));

        assertThat(firstLogEntry.getLoggerName(), is("MyTest"));

    }

}

class TestAppender extends AppenderSkeleton {

    private final List<LoggingEvent> log = new ArrayList<LoggingEvent>();

    @Override

    public boolean requiresLayout() {

        return false;

    }

    @Override

    protected void append(final LoggingEvent loggingEvent) {

        log.add(loggingEvent);

    }

    @Override

    public void close() {

    }

    public List<LoggingEvent> getLog() {

        return new ArrayList<LoggingEvent>(log);

    }

}

0 votes
by (3.1k points)

Its vey simple to assert Junit on a message in a logger with some simple steps 

Step 1: Add Dependencies 
If you’re using Maven, add the following dependencies to your pom.xml: 
 
xml 
<dependency> 
<groupId>nl.altindag.logcaptor</groupId> 
<artifactId>logcaptor</artifactId> 
<version>2.15.1</version> <!-- Check for the latest version --> 
<scope>test</scope> 
</dependency> 
Step 2: Use LogCaptor in Your Test 
Here’s an example of how to use LogCaptor to assert on log messages in a JUnit test: 
 
java 
import nl.altindag.logcaptor.LogCaptor; 
import org.junit.jupiter.api.Test; 
 
import static org.junit.jupiter.api.Assertions.assertEquals; 
 
public class MyServiceTest { 
 
@Test 
public void testLogging() { 
LogCaptor logCaptor = LogCaptor.forClass(MyService.class); 
 
MyService myService = new MyService(); 
myService.doSomething(); // This method should log a message 
 
// Capture the log messages 
String loggedMessage = logCaptor.getInfoLogs().get(0); 
 
// Assert the expected log message 
assertEquals("Expected log message", loggedMessage); 
} 
} 
Step 3: Implement the Logging in Your Service 
Ensure your service is logging the message as follows: 
 
java 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
 
public class MyService { 
private static final Logger logger = LoggerFactory.getLogger(MyService.class); 
 
public void doSomething() { 
logger.info("Expected log message"); 
} 
} 

Related questions

0 votes
1 answer
0 votes
1 answer
0 votes
1 answer
0 votes
2 answers
asked Oct 15, 2019 in Java by Shubham (3.9k points)

1.2k questions

2.7k answers

501 comments

693 users

Browse Categories

...