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 ListFollowing method adds the custom appender to the logger: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; } }
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")); }