测试错误处理器日志语句:SLF4J Test日志未填充问题求助
问题:SLF4J Test日志断言失败,日志列表始终为空
我基于流程中抛出的MessagingException负载类型实现了自定义错误日志处理器,代码如下:
@ServiceActivator public void handleThrowable(Message<Throwable> errorMessage) { var throwable = errorMessage.getPayload(); log.error("Error in Processing. Message: {}", throwable.getMessage(), throwable); if (throwable instanceof MessagingException) { var messagingException = (MessagingException) throwable; var failedMessage = messagingException.getFailedMessage(); log.error("Failed Message: {}", failedMessage); if (!Objects.isNull(failedMessage)) { var msg = failedMessage.getPayload(); var headers = failedMessage.getHeaders(); if (msg instanceof File) { log.error("Failed consuming File: {}", ((File) msg).getAbsolutePath()); } if (msg instanceof String) { log.error("Failed to create a CsvEmailInteraction from line {}. Line was: {}", headers.get(IntegrationMessageHeaderAccessor.SEQUENCE_NUMBER), msg); } if (msg instanceof CsvEmailInteraction) { var csvObject = (CsvEmailInteraction) msg; log.error("Failed to publish CsvEmailInteraction to Kafka. messageId was: {}", csvObject.getMessageId()); } } } }
我使用SLF4J Test » 1.2.0编写测试代码,但在断言部分尝试获取日志时,日志列表始终未被填充。以下是针对String类型负载的测试代码(其他类型测试逻辑类似):
class DefaultErrorChannelServiceActivatorSpec extends Specification { def serviceActivator = new DefaultErrorChannelServiceActivator() TestLogger testLogger = TestLoggerFactory.getTestLogger(DefaultErrorChannelServiceActivator.class) def "test handleThrowable with MessagingException instance of String"() { given: // Create a MessagingException with a failed message def failedMessage = new GenericMessage<>("This is a failed string message") def messagingException = Mock(MessagingException) testLogger.clear() Message<Throwable> throwableMessage = MessageBuilder.withPayload(messagingException).build() when: serviceActivator.handleThrowable(throwableMessage) then: 1 * messagingException.getFailedMessage() >> failedMessage // def logs = testLogger.getAllLoggingEvents() // logs.contains("Failed Message") } }
修复方案
确保日志绑定唯一性
测试依赖中仅保留org.slf4j:slf4j-test:1.2.0,排除其他SLF4J绑定(如logback-classic、log4j-slf4j-impl),避免日志被其他实现拦截。对齐Logger初始化类
检查DefaultErrorChannelServiceActivator中的日志实例是否使用自身类初始化:
private static final Logger log = LoggerFactory.getLogger(DefaultErrorChannelServiceActivator.class);
必须和测试中TestLoggerFactory.getTestLogger(...)传入的类一致,否则测试Logger无法捕获目标类的日志。
- 补充Mock缺失的方法调用
处理器会调用throwable.getMessage(),补充该Mock避免空值影响日志输出:
then: 1 * messagingException.getFailedMessage() >> failedMessage 1 * messagingException.getMessage() >> "Test error message"
- 使用正确的断言方式
SLF4J Test提供了更易用的断言方法,替代手动遍历日志事件:
then: // 验证特定格式的ERROR日志是否被记录 testLogger.errorLogged("Failed Message: {}", failedMessage) // 验证String负载对应的日志内容 testLogger.errorLogged("Failed to create a CsvEmailInteraction from line null. Line was: This is a failed string message")
(注:SEQUENCE_NUMBER未设置,所以此处为null)
- 显式设置日志级别
确保TestLogger的级别不会过滤ERROR日志(默认级别为INFO,ERROR会被捕获,可显式设置确保):
given: testLogger.setLevel(Level.ERROR)
内容的提问来源于stack exchange,提问作者Beez
相关产品推荐
相关产品推荐

