在不使用 Log4J 的情况下测试 Slf4j 创建的日志消息
Testing Log Messages Created by Slf4j Without Using Log4J
我想测试一种方法是否创建了正确的日志。我的 class 看起来像这样:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
class EventLogHandler {
private final Logger logger = LoggerFactory.getLogger(EventLogHandler.class);
private final Marker eventMarker = MarkerFactory.getMarker("EVENT");
public void handle(final Event event) {
final String log = SomeOtherClass.createLog(event);
logger.info(eventMarker, log);
}
}
我看到一些examples/solutions用于测试日志,但它们都在使用我们在项目中没有使用的Log4j。我只能用spring-boot的Log4j2,Slf4j和Logback classic。
我如何用现有的依赖项测试 handle(...) 方法?
在当前的实现中,您不能 test/verify 在 logger
上调用而不使用日志系统并断言其输出,例如引入 logback 并使用 stdout appender 配置它并捕获 stdout 并对其进行断言等。
为了在不执行任何操作的情况下测试您的 class,您必须亲身体验 EventLogHandler
中使用的 logger
实例。当前的实现通过像这样构建 logger
来增加难度:
private final Logger logger = LoggerFactory.getLogger(EventLogHandler.class);
在这种情况下进行测试的一种常见方法是重构记录器的创建,以便在 运行 测试时将模拟实例注入 EventLogHandler
。例如:
class EventLogHandler {
private final Marker eventMarker = MarkerFactory.getMarker("EVENT");
private final Logger logger;
public EventLogHandler() {
this(LoggerFactory.getLogger(EventLogHandler.class));
}
// probably only used by your test case
public EventLogHandler(Logger logger) {
this.logger = logger;
}
public void handle(final Event event) {
logger.info(eventMarker, log);
}
}
然后像这样测试它:
@Test
public void someTest() {
Logger logger = Mockito.mock(Logger.class);
EventLogHandler sut = new EventLogHandler(logger);
sut.handle(event);
// verify that the right state is extracted from the given event and that the correct marker is used
Mockito.verify(logger).info(..., ...);
}
一个不太常见的替代方法是使用 Powermock 来模拟此调用:LoggerFactory.getLogger(EventLogHandler.class);
然后使用 Mockito 以与上面所示相同的方式验证对其的调用..
我想测试一种方法是否创建了正确的日志。我的 class 看起来像这样:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
class EventLogHandler {
private final Logger logger = LoggerFactory.getLogger(EventLogHandler.class);
private final Marker eventMarker = MarkerFactory.getMarker("EVENT");
public void handle(final Event event) {
final String log = SomeOtherClass.createLog(event);
logger.info(eventMarker, log);
}
}
我看到一些examples/solutions用于测试日志,但它们都在使用我们在项目中没有使用的Log4j。我只能用spring-boot的Log4j2,Slf4j和Logback classic。 我如何用现有的依赖项测试 handle(...) 方法?
在当前的实现中,您不能 test/verify 在 logger
上调用而不使用日志系统并断言其输出,例如引入 logback 并使用 stdout appender 配置它并捕获 stdout 并对其进行断言等。
为了在不执行任何操作的情况下测试您的 class,您必须亲身体验 EventLogHandler
中使用的 logger
实例。当前的实现通过像这样构建 logger
来增加难度:
private final Logger logger = LoggerFactory.getLogger(EventLogHandler.class);
在这种情况下进行测试的一种常见方法是重构记录器的创建,以便在 运行 测试时将模拟实例注入 EventLogHandler
。例如:
class EventLogHandler {
private final Marker eventMarker = MarkerFactory.getMarker("EVENT");
private final Logger logger;
public EventLogHandler() {
this(LoggerFactory.getLogger(EventLogHandler.class));
}
// probably only used by your test case
public EventLogHandler(Logger logger) {
this.logger = logger;
}
public void handle(final Event event) {
logger.info(eventMarker, log);
}
}
然后像这样测试它:
@Test
public void someTest() {
Logger logger = Mockito.mock(Logger.class);
EventLogHandler sut = new EventLogHandler(logger);
sut.handle(event);
// verify that the right state is extracted from the given event and that the correct marker is used
Mockito.verify(logger).info(..., ...);
}
一个不太常见的替代方法是使用 Powermock 来模拟此调用:LoggerFactory.getLogger(EventLogHandler.class);
然后使用 Mockito 以与上面所示相同的方式验证对其的调用..