Skip to content

Instantly share code, notes, and snippets.

@jakzal
Created May 19, 2021 09:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jakzal/d6bb2c83ac07bd6d133967ce7ea934c5 to your computer and use it in GitHub Desktop.
Save jakzal/d6bb2c83ac07bd6d133967ce7ea934c5 to your computer and use it in GitHub Desktop.
JUnit extension for logger tests
package com.kaffeinelabs;
import com.kaffeinelabs.test.junit.extension.LoggerExtension;
import org.junit.jupiter.api.Test;
class FooTest {
@RegisterExtension
LoggerExtension loggerExtension = LoggerExtension.forLogger(Foo.class);
@Test
public void testItLogsTheError() {
// ...
loggerExtension.assertErrorLogged(
"Big error.",
Map.of(
"error-id", "edd33765-f6f0-49b8-81fc-4e95b2073a81",
"request-id", "51b31c7a-4f7a-4e57-aecd-d2a3f516dc61
)
);
}
}
package com.kaffeinelabs.test.junit.extension;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.opentest4j.AssertionFailedError;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.stream.Collectors;
public class LoggerExtension implements BeforeEachCallback, AfterEachCallback {
public final ListAppender<ILoggingEvent> logAppender;
private final Logger logger;
private LoggerExtension(final Class loggerType) {
logger = (Logger) LoggerFactory.getLogger(loggerType);
logAppender = new ListAppender<>();
}
public static LoggerExtension forLogger(final Class loggerType) {
return new LoggerExtension(loggerType);
}
@Override
public void beforeEach(final ExtensionContext extensionContext) {
logAppender.start();
logger.addAppender(logAppender);
}
@Override
public void afterEach(final ExtensionContext extensionContext) {
logger.detachAppender(logAppender);
logAppender.stop();
}
public void assertErrorLogged(String message) {
assertErrorLogged(message, Map.of());
}
public void assertErrorLogged(String message, Map<String, String> context) {
logAppender.list.stream()
.filter(e -> e.getMessage().equals(message) && e.getMDCPropertyMap().equals(context))
.findFirst()
.orElseThrow(() -> new AssertionFailedError(String.format(
"Message was not logged: %s %s\nLogged messages (%d):\n%s",
message,
context,
logAppender.list.stream().count(),
logAppender.list.stream().map(e -> String.format("%s %s", e.getMessage(), e.getMDCPropertyMap())).collect(Collectors.joining("\n"))
)));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment