Skip to content

Spring单元测试日志断言

334字约1分钟

spring单元测试

2024-12-22

在使用springboot test做单元测试时,我们需要根据输出的日志内容进行断言。但是,spring并没有直接提供可用的方式,本文将介绍如何在spring单元测试中根据日志输出内容进行断言。

1. 引入依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
</dependencies>

提示

本文使用的是log4j2,如需使用logback或其他日志框架,请自行查看文档,继承对应框架的日志抽象类实现。

2. 实现自定义Appender

import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.Layout;

public class MemoryAppender extends AbstractAppender {

  private List<String> messages = new ArrayList<>();

  protected MemoryAppender(Layout<? extends Serializable> layout) {
    super("MemoryAppender", null, layout, true, Property.EMPTY_ARRAY);
  }

  @Override
  public void append(LogEvent logEvent) {
    String message = new String(getLayout().toByteArray(logEvent));
    messages.add(message);
  }

  public List<String> getMessages() {
    return messages;
  }
}

3. 注册自定义Appdener

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.*;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.List;

@SpringBootTest
public class LogCaptureTest {

  private static final org.slf4j.Logger LOGGER = 
                      LoggerFactory.getLogger(LogCaptureTest.class);

  @Test
  public void test() {
    Logger rootLogger = (Logger) LogManager.getRootLogger();
    LoggerContext context = rootLogger.getContext();
    // 获取console appender
    ConsoleAppender consoleAppender = context.getConfiguration().getAppender("console");
    // 获取控制台日志格式
    Layout<? extends Serializable> layout = consoleAppender.getLayout();
    MemoryAppender memoryAppender = new MemoryAppender(layout);
    rootLogger.addAppender(memoryAppender);
    context.updateLoggers();

    LOGGER.info("Hello");
    System.out.println("messages: " + memoryAppender.getMessages());
    Assertions.assertTrue(memoryAppender.getMessages().contains("Hello"));
  }
}