Sometimes asserting on a log statement might be the only way of validating a method call. One way of asserting log statements is to create a custom appender and attaching it to the logger to capture the logs. log4j-api provides the framework to create a custom appender.
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class CustomAppender extends AbstractAppender {
private List messages = new ArrayList<>();
public CustomAppender(String name, Filter filter, Layout layout) {
super(name, filter, layout);
}
public CustomAppender(String name, Filter filter, Layout layout, boolean ignoreExceptions) {
super(name, filter, layout, ignoreExceptions);
}
@Override
public void append(LogEvent event) {
byte[] data = getLayout().toByteArray(event);
messages.add(new String(data).trim()); // optional trim
}
@Override
public void stop() {
}
public List getMessages() {
return messages;
}
}
Following method adds the custom appender to the logger:
private void setUpLogHandler() {
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final AbstractConfiguration config = (AbstractConfiguration) ctx.getConfiguration();
// Create and add the appender
customAppender = new CustomAppender("Custom", null, PatternLayout.createDefaultLayout());
customAppender.start();
config.addAppender(customAppender);
// Create and add the logger
AppenderRef[] refs = new AppenderRef[]{AppenderRef.createAppenderRef("Custom", null, null)};
LoggerConfig loggerConfig = LoggerConfig.createLogger("false", Level.INFO, ClassUnderTest.class.getCanonicalName(), "true", refs, null, config, null);
loggerConfig.addAppender(customAppender, null, null);
config.addLogger(ClassUnderTest.class.getCanonicalName(), loggerConfig);
ctx.updateLoggers();
}
Below is an example test method which asserts on a method that logs:
@Test
public void logTest() {
setUpLogHandler();
ClassUnderTest ct = new ClassUnderTest();
ct.methodThatLogs();
assertThat(customAppender.getMessages(), hasItem("new log message"));
}
No comments:
Post a Comment