Describes how to use Mockito to verify log messages in Unit tests.
The main libraries are as follows
Library | version |
---|---|
Junit | 4.12 |
mockito | 1.10.19 |
log4j | 2.6.2 |
I am using Maven. Please refer to the link below for the detailed version. pom.xml
The classes to be tested are as follows. Calling the sayHello method prints a message to the log at the INFO level. Log output uses log4j.
HelloWorld.java
class HelloWorld {
private Logger logger = LogManager.getLogger(this);
void sayHello(String name) {
logger.info("Hello " + name);
}
}
You will need an Appender Mock object to get the log messages. We also prepare an ArgumentCaptor to get the value of the argument from the Mock object.
HelloWorldTest.java
@Mock
private Appender mockAppender;
@Captor
private ArgumentCaptor<LogEvent> logCaptor;
Set the Appender object prepared above to log4j. At this time, specify the value to be returned by Mockito so that it will operate as an Appender when the mockAppender object is called from log4j.
HelloWorldTest.java
Mockito.reset(mockAppender);
//Set the name of the Appender
Mockito.when(mockAppender.getName()).thenReturn("MockAppender");
//Set to be ready to be used as an Appender (bottom 2 lines)
Mockito.when(mockAppender.isStarted()).thenReturn(true);
Mockito.when(mockAppender.isStopped()).thenReturn(false);
//Take out the ROOT logger and set the Appender.
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.setLevel(Level.INFO);
loggerConfig.addAppender(mockAppender, Level.INFO, null);
ctx.updateLoggers();
The actual test code is as follows. Extract the message from the Appender's append method. You can also check the number of calls. This time, it is clearly specified as 1 because it is once.
HelloWorldTest.java
@Test
public void outputLogMessage() {
String name = "World";
HelloWorld helloWorld = new HelloWorld();
helloWorld.sayHello(name);
Mockito.verify(mockAppender, Mockito.times(1)).append(logCaptor.capture());
String message = logCaptor.getValue().getMessage().getFormattedMessage();
Level level = logCaptor.getValue().getLevel();
assertThat(message, is("Hello " + name));
assertThat(level, is(Level.INFO));
}
Described how to verify log messages by using Mockito to get the arguments of Appender's append object. This allows for log-level verification as well as messages.
Before I knew how to do this, I had a lot of trouble parsing the strings output to the log file. Say goodbye to such hardships.
The source code is available below. If you want to try it out, please refer to it.
https://github.com/hiroyuki-kaneko/testforlog
Recommended Posts