【问题标题】:Testing Log Output Java Spring测试日志输出 Java Spring
【发布时间】:2018-12-06 14:34:07
【问题描述】:

我有一个使用 SLF4J 和 logback 作为底层记录器的 java 10 上运行的 spring boot 2 应用程序。

给定以下弹簧组件:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class MyClass {

    private static final Logger LOG = LoggerFactory.getLogger(MyClass.class);

    public void hello() {
        // more logic...
        LOG.trace("World");
    }
}

希望验证日志输出的测试(想象一个更复杂的场景,其中日志将包含变量和上下文信息)或生成日志消息的事实被认为是关键的。

import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.test.rule.OutputCapture;

import static org.hamcrest.Matchers.containsString;

public class MyClassTest {

    private final MyClass myClass = new MyClass();

    @Rule
    public final OutputCapture outputCapture = new OutputCapture();

    @Test
    public void successShouldLogSuccessMessages() {
        myClass.hello();
        outputCapture.expect(containsString("World"));
    }
}

要通过此测试,日志级别必须设置为TRACE。我注意到一些不可预知的行为,根据测试运行的顺序,测试要么失败要么通过 - 请参阅Seemingly Random Test Failure With Maven & Spring Boot 2 When A WebFluxTest Is Introduced

我已经探索了一些选项,但没有一个看起来“理想”但确实有效。

  1. 在测试类路径上提供一个日志返回配置文件,该文件将日志级别设置为至少跟踪这一类。
  2. 在 Spring 应用程序属性类中将此类的日志级别设置为 TRACE,并在 Spring 上下文中运行测试。
  3. 在测试类中创建一个设置并拆除,该类在测试执行期间以编程方式修改日志级别,然后在之后将其重置。

我目前的解决方案是让 Spring 完成配置记录器的工作,并使测试成为 Spring 上下文测试(并确保它快速运行,只加载我关心的一个 bean)如下:

@RunWith(SpringRunner.class)
@SpringBootTest(properties = "spring.profiles.active=test")
@ContextConfiguration(classes = MyClass.class)
public class MyClassTest {

    private final MyClass myClass = new MyClass();

    @Rule
    public final OutputCapture outputCapture = new OutputCapture();

    @Test
    public void successShouldLogSuccessMessages() {
        myClass.hello();
        outputCapture.expect(containsString("World"));
    }
}

application-test.properties的内容在哪里:

logging.level.com.example.MyClass=TRACE

此解决方案有效,它不需要我以编程方式使用记录器或将 logback 配置放在类路径上,这使所有内容都与底层日志框架完全不可知,并且使 logback 配置远离测试类路径也意味着其他测试不关心日志记录不选择配置。

也就是说,感觉“奇怪”,我从未真正见过有人以这种方式使用 spring 测试(测试没有依赖关系且不直接依赖上下文的单个 bean)。该测试以计划 POJO 测试开始,不关心春天,感觉更“纯粹”,保持这种状态。

在尝试通过 SLF4J 测试对象的日志输出时,是否有适用的最佳实践?

【问题讨论】:

    标签: java junit logback slf4j spring-boot-test


    【解决方案1】:

    您的方法是测试您当前的日志记录配置记录的内容,而不是发送到日志记录系统的内容。

    您可以通过编写自己的附加程序或模拟 SLF4J 实现来intercept the logging,而不是 OutputCapture 规则。如果记录了不正确的内容such as an error,您甚至可能无法在自定义附加程序中进行测试。我建议您创建自己的 @Rule 来添加您自己的测试附加程序,然后它可以执行您想要检查匹配器或确保记录正确数据的任何自定义逻辑。

    【讨论】:

      猜你喜欢
      • 2019-04-07
      • 2018-05-29
      • 2021-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 2015-12-24
      相关资源
      最近更新 更多