在 Java 中测试 Logger(如 SLF4J / Logback / java.util.logging) 时,通常不建议直接 mock Logger 本身,而是验证“是否输出了预期的日志”。下面按常见场景给你几种实用做法。
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")));
}
}
✅ 优点:
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private Logger logger;
@InjectMocks
private UserService userService;
@Test
void shouldCallLogger() {
userService.doSomething();
verify(logger).info(contains("start"));
}
}
⚠️ 问题:
private static finalHandler 捕获@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")));
}
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 | 不推荐 |
如果你愿意,可以告诉我:
我可以直接给你一套可复制的测试代码。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。