温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java Logger 如何测试mock

发布时间:2026-09-12 12:15:09 来源:亿速云 阅读:85 作者:小樊 栏目:编程语言

在 Java 中测试 Logger(如 SLF4J / Logback / java.util.logging) 时,通常不建议直接 mock Logger 本身,而是验证“是否输出了预期的日志”。下面按常见场景给你几种实用做法


一、最推荐:使用 Log 捕获工具(不 mock)

1️⃣ SLF4J + Logback → ListAppender

依赖

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <scope>test</scope>
</dependency>

测试示例

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.Test;
import org.slf4j.LoggerFactory;

import static org.junit.jupiter.api.Assertions.*;

class UserServiceTest {

    @Test
    void shouldLogWhenUserNotFound() {
        Logger logger = (Logger) LoggerFactory.getLogger(UserService.class);
        ListAppender<ILoggingEvent> appender = new ListAppender<>();
        appender.start();
        logger.addAppender(appender);

        new UserService().findUser(1L);

        assertTrue(appender.list.stream()
                .anyMatch(e -> e.getFormattedMessage().contains("user not found")));
    }
}

✅ 优点:

  • 不 mock
  • 验证真实日志行为
  • 适合单元测试 & 集成测试

二、Mock Logger(不推荐但可用)

2️⃣ 使用 Mockito mock Logger

@ExtendWith(MockitoExtension.class)
class UserServiceTest {

    @Mock
    private Logger logger;

    @InjectMocks
    private UserService userService;

    @Test
    void shouldCallLogger() {
        userService.doSomething();

        verify(logger).info(contains("start"));
    }
}

⚠️ 问题:

  • Logger 通常是 private static final
  • 需要可注入(破坏设计)
  • 只验证“调用”,不验证“输出”

三、java.util.logging(JUL)

3️⃣ 使用 Handler 捕获

@Test
void testLog() {
    Logger logger = Logger.getLogger(MyClass.class.getName());
    TestHandler handler = new TestHandler();
    logger.addHandler(handler);

    new MyClass().run();

    assertTrue(handler.getLogs().stream()
            .anyMatch(l -> l.contains("error")));
}

四、Spring / Spring Boot 项目

4️⃣ 使用 OutputCapture

@SpringBootTest
class AppTest {

    @Test
    void logTest(UnsupportedLookAndFeelException ex) {
        // 使用 Spring Boot Test 的 OutputCapture
    }
}

或更常见:

@ExtendWith(OutputCaptureExtension.class)
@Test
void testLog(CapturedOutput output) {
    userService.run();
    assertTrue(output.getOut().contains("started"));
}

✅ 总结建议

场景 推荐方式
SLF4J ListAppender
JUL Handler
Spring Boot OutputCapture
纯 Mockito 不推荐

如果你愿意,可以告诉我:

  • 用的是 SLF4J / Log4j / JUL
  • JUnit 4 还是 5
  • 是否 Spring 项目

我可以直接给你一套可复制的测试代码。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI