如何使用 WebTestClient + Micrometer Tracer 测试 TraceId 传播?

Ben*_*tte 5 spring spring-boot spring-boot-actuator micrometer-tracing

迁移到 Spring Boot 3 并从 Sleuth 重构为 Micrometer 后,我无法再使用 WebTestClient + Tracer 测试 TraceId 传播。

我在这里的测试是有一个简单的 @RestController ,我希望通过 Tracer 传播 traceId :

@RestController
class MyTraceIdController(@Autowired private val tracer: Tracer) {


    @GetMapping("/trace")
    fun info(): ResponseEntity<String> {

        val traceKey = "x-b3-traceid"

        // Using tracer the traceId is retrieved at runtime but not during test
        val responseHeaders = HttpHeaders()
        responseHeaders.set(traceKey, tracer.currentSpan()?.context()?.traceId().toString())

        return ResponseEntity
            .ok()
            .headers(responseHeaders)
            .body("OK")
    }

}
Run Code Online (Sandbox Code Playgroud)

我们的目标是通过 WebTestClient 来测试它:

@AutoConfigureWebTestClient
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class MyTraceIdTests(@Autowired private val webTestClient: WebTestClient) {

    @Test
    fun `Assert info endpoint works as expected with webTestClient`() {

        val traceKey = "x-b3-traceid"
        val traceValue = "463ac35c9f6413ad48485a3953bb6124"

        val spanKey = "x-b3-spanid"
        val spanValue = "a2fb4a1d1a96d312"

        webTestClient.get()
            .uri("http://localhost:9080/trace")
            .header(traceKey, traceValue)
            .header(spanKey, spanValue)
            .exchange()
            .expectStatus().isOk
            .expectHeader().valueEquals(traceKey, traceValue)
            .expectBody<String>().isEqualTo("OK")
    }

}
Run Code Online (Sandbox Code Playgroud)

使用 Sleuth,在运行测试时,注入的 BraveTracer 完美地完成了传播 TraceId 的工作。

有了 Micrometer,我就无法再注入正确的示踪剂来完成这项工作。

为了测试该案例,我创建了以下示例:

https://github.com/bvoglevette/trace-id-sample

可以观察到两种行为:

  • 运行时,在端点上执行 bootRun +curl,使用 BraveAutoconfiguration 并注入一个正确的 BraveTracer =>它按预期工作
  • 测试时,我无法注入一个正确的 BraveTracer bean => TraceId 始终为 null

我尝试过的不同方法都没有成功

  • 使用 SimpleTracer()
  • 要实现我自己的 Tracer bean,请遵循 Micrometer 文档
  • 在我的测试中使用 BraveAutoconfiguration 或基于它实例化 beans

这些实现都无法生成一个 Bean 来传播 TraceId。

我希望更多人找到一种方法来简单地注入来自 BraveAutoconfiguration 的工作 bean。我缺少什么?我应该以不同的方式进行测试吗?

Mar*_*zak 10

您需要添加@AutoConfigureObservability您的测试类。默认情况下,在测试中禁用可观察性。