如何断言Lombok @Slf4j日志器?测试Flux空值日志输出
测试Flux为空时的日志输出方案
不用弃用Lombok,有几种实用方案可以验证这段日志输出:
1. 用日志捕获工具直接抓输出
很多Java测试生态里的工具可以直接捕获日志,不用mock日志对象。比如用SLF4J配套的logback提供的ListAppender,直接把目标类的日志输出收集起来再断言:
import org.junit.jupiter.api.Test; import org.slf4j.LoggerFactory; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.read.ListAppender; import reactor.core.publisher.Flux; class SomeClassTest { @Test void testEmptyFluxTriggersWarnLog() { // 获取SomeClass对应的日志实例 Logger targetLogger = (Logger) LoggerFactory.getLogger(SomeClass.class); // 创建一个用于收集日志的ListAppender ListAppender<ILoggingEvent> logCollector = new ListAppender<>(); logCollector.start(); targetLogger.addAppender(logCollector); // 执行测试方法,传入空Flux SomeClass testInstance = new SomeClass(); testInstance.someMethod(Flux.empty()); // 检查是否有符合条件的WARN日志 boolean hasExpectedWarn = logCollector.list.stream() .anyMatch(event -> event.getLevel() == ch.qos.logback.classic.Level.WARN && event.getMessage().equals("No integers!")); assert hasExpectedWarn; } }
2. 微调代码,给日志留测试注入入口
如果觉得抓日志的方式不够直接,可以稍微改一下代码,保留Lombok的@Slf4j,同时给日志字段加个包级别的Setter,方便测试时注入mock对象:
@Slf4j class SomeClass { // 保留Lombok生成的默认日志实例,同时加Setter用于测试 @Setter(AccessLevel.PACKAGE) private Logger log = log; void someMethod(Flux<Integer> intFlux) { intFlux.switchIfEmpty(Mono.defer(() -> { log.warn("No integers!"); return Mono.empty(); })) .subscribe(/* consume */); } }
测试时就可以用Mockito mock日志对象,然后验证调用:
import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.slf4j.Logger; import reactor.core.publisher.Flux; class SomeClassTest { @Test void testEmptyFluxLogsWarn() { Logger mockLogger = Mockito.mock(Logger.class); SomeClass testInstance = new SomeClass(); testInstance.setLog(mockLogger); testInstance.someMethod(Flux.empty()); // 验证warn方法被调用了一次,参数正确 Mockito.verify(mockLogger).warn("No integers!"); } }
这种方式既不丢Lombok的便利,又解决了测试验证的问题。
3. PowerMock(不推荐)
PowerMock可以直接mock静态生成的log字段,但它会修改类加载器,容易导致测试复杂度上升、和其他框架兼容出问题,除非万不得已不建议用。
总结:优先选日志捕获或者微调代码的方案,完全没必要弃用Lombok。
内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

