Mockito 单元测试 lombok.extern.slf4j @Slf4j 注解日志?

enn*_*nth 7 unit-testing annotations slf4j mockito lombok

我有一个方法,它在内部调用一个名为“burn”的方法,该方法会引发数据异常,如果是这样,那么它会被捕获在 try/catch 块中并记录到记录器中。然而,该类使用注释 @Slf4j 和 lombok.extern.slf4j:

@Slf4j
public class MyClass {

 private void myMethod(Type parameter) throws Exception {
     try {
        dataGateway.burn(id);
         }
     catch {
        log.error("Failed to burn({})",id);
        }
  }
Run Code Online (Sandbox Code Playgroud)

我已经模拟了数据网关,并让它在调用 burn 时抛出异常,我知道异常已被捕获,但如何使用验证来断言记录器被调用为 .error?DateGateway dBMock = mock(DateGateway.class);

when(dBMock.burn(anyString())).thenReturn(new DataException("exception"));
Run Code Online (Sandbox Code Playgroud)

Fre*_*rik 5

我在这里找到了这个问题的一个很好的解决方案:https://www.jvt.me/posts/2019/09/22/testing-slf4j-logs/

解决方案是向要测试的类添加一个日志附加程序,然后读取从该附加程序记录的内容。

以下是为特定类添加和返回附加程序的通用方法:

private ListAppender<ILoggingEvent> getListAppenderForClass(Class clazz) {
    Logger logger = (Logger) LoggerFactory.getLogger(clazz);
    ListAppender<ILoggingEvent> loggingEventListAppender = new ListAppender<>();
    loggingEventListAppender.start();
    logger.addAppender(loggingEventListAppender);
    return loggingEventListAppender;
}
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您可以在测试中使用此附加程序来验证是否调用了您的特定日志行:

final ListAppender<ILoggingEvent> listAppenderForClass = getListAppenderForClass(CardApi.class);
org.assertj.core.api.Assertions.assertThat(listAppenderForClass.list)
                .extracting(ILoggingEvent::getFormattedMessage)
                .anyMatch((Predicate<String>) s -> s.startsWith("Failed to burn"));
Run Code Online (Sandbox Code Playgroud)