【问题标题】:How can I test logs of Spring Boot application?如何测试 Spring Boot 应用程序的日志?
【发布时间】:2021-05-27 23:46:51
【问题描述】:

我有一个混合了 Spring Boot、Jersey 和 Camel 应用程序的应用程序。它以 Spring Boot 应用程序开始。我正在编写集成测试,我需要在日志上进行断言?

例如,我需要断言 Camel 路由从源 A 读取了一条消息。如何在日志上做出可靠的断言?有没有这方面的行业标准?

注意:我尝试找到任何解决方案,但目前我既不明白如何解决,也找不到现成的解决方案。

更新 1: 我低估的细节,但似乎很重要。我使用Kotlin,而不是Java。我尝试申请answer,但它不能一对一转移到Kotlin

更新 2:

这是从JavaKotlin 的转换。 ListAppender 没有足够的信息来解析 Kotlin 中的类型。

class LoggerExtension : BeforeEachCallback, AfterEachCallback {
    private val listAppender: ListAppender<ILoggingEvent> = ListAppender<ILoggingEvent>()
    private val logger: Logger = LoggerFactory.getLogger(ROOT_LOGGER_NAME) as Logger

    override fun afterEach(extensionContext: ExtensionContext) {
        listAppender.stop()
        listAppender.list.clear()
        logger.detachAppender(listAppender)
    }

    override fun beforeEach(extensionContext: ExtensionContext) {
        logger.addAppender(listAppender)
        listAppender.start()
    }

    val messages: List<String>
        get() = listAppender.list.stream().map { e -> e.getMessage() }.collect(Collectors.toList())
    val formattedMessages: List<String>
        get() = listAppender.list.stream().map { e -> e.getFormattedMessage() }.collect(Collectors.toList())
}

Kotlin:没有足够的信息来推断类型变量 A

不是错误,但我感觉它会在运行时失败:

private val logger:Logger = LoggerFactory.getLogger(ROOT_LOGGER_NAME) as Logger

【问题讨论】:

  • 你提到的答案有什么问题?有什么错误吗?
  • 我不知道我的经历是否不寻常,但我从未将日志输出视为函数/类/系统契约的一部分,因此从未想过对其进行测试。日志输出变化很大:它取决于日志级别和配置,开发人员经常根据需要添加/更改/删除日志来调查问题——你不希望每次测试都失败。并且日志通常是供人眼使用的,而不是供机器解析的,因此日志更改无论如何都不应该破坏任何东西。如果您有重要的输出,您是否考虑过将其写入日志之外的其他地方
  • @gidds 这是个好问题。理论上,可以将所有日志重定向到文件并在文件中断言,但它与断言日志有何不同。另外,就我而言,我们有一个微服务架构,我想知道 Camel 是否从队列中读取了消息。因为我想知道路由是否正常工作,我没有看到比分析日志更好的测试方法。我猜这种做法特定于 Apache Camel 框架。

标签: spring spring-boot kotlin logging integration-testing


【解决方案1】:

Spring Boot 带有适用于 JUnit 4 的 OutputCapture 规则和适用于 JUnit 5 的 OutputCaptureExtension 规则,可让您对发送到标准输出的文本进行断言。

public class MyTest {

     @Rule
     public OutputCaptureRule output = new OutputCaptureRule();

     @Test
     public void test() {
         // test code
         assertThat(output).contains("ok");
     }

 }

【讨论】:

  • 谢谢,我不知道这个选项在 Spring Boot 中可用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-05
相关资源
最近更新 更多