You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何断言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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 17:03:21