如何在MockMvc的单元测试中启用Spring Cloud Sleuth

问题描述

我们有一个Spring Boot Rest API(Spring Boot 2.3.0.RELEASE),它使用Spring Cloud Sleuth(2.2.3.RELEASE版本)。

在某些时候,我们使用来自弹簧侦探的跟踪ID作为数据。通过自动装配Tracing bean,然后访问当前范围来获取跟踪ID。可以说我们定义了一个带有以下内容的bean SimpleCorrelationBean:

@Autowired
private Tracer tracer;

public String getCorrelationId() {
    return tracer.currentSpan().context().traceIdString();
} 

这似乎在运行spring boot应用程序时完美地工作,但是当我们尝试在单元测试中访问tracer.currentSpan()时,此属性为null。看来弹簧云侦探在运行测试时没有创建任何跨度。

我认为这与在单元测试期间设置的应用程序上下文有关,但是我不知道如何为测试应用程序上下文启用spring cloud sleuth。

下面是一个简单的测试类,其中的错误发生在simpleTest1中。在simpleTest2中,不会发生错误

simpleTest1错误,因为tracer.currentSpan()为空

@ExtendWith({ RestDocumentationExtension.class,SpringExtension.class })
@SpringBoottest(classes = MusicService.class)
@WebAppConfiguration
@ActiveProfiles("unit-test")
@ComponentScan(basePackageClasses = datacast2.data.JpaConfig.class)
public class SimpleTest {
    
    private static final Logger logger = LoggerFactory.getLogger(SimpleTest.class);
    
    @Autowired
    private WebApplicationContext context;

    private mockmvc mockmvc;
    
    @Autowired
    private FilterChainProxy springSecurityFilterChain;
    
    @Autowired
    private SimpleCorrelationBean simpleCorrelationBean;
    
    @Autowired
    private Tracer tracer;
    
    @BeforeEach
    public void setup(RestDocumentationContextProvider restDocumentation) throws Exception {

        this.mockmvc = mockmvcBuilders.webAppContextSetup(this.context)
                .apply(documentationConfiguration(restDocumentation))
                .addFilter(springSecurityFilterChain).build();

    }
    
    @Test
    public void simpleTest1() throws Exception {
        try {
            String correlationId = simpleCorrelationBean.getCorrelationId();
        }catch(Exception e) {
            logger.error("This seem to fail.",e);
        }
        
    }
    
    @Test
    public void simpleTest2() throws Exception {
        
        //It looks like spring cloud sleuth is not creating a span,so we create one ourselfs
        Span newSpan = this.tracer.nextSpan().name("simpleTest2");
                
        try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(newSpan.start())) {
            String correlationId = simpleCorrelationBean.getCorrelationId();
        }
        finally {
            newSpan.finish();
        }
    }

}

问题是:如何在单元测试期间为mockmvc启用Spring Cloud Sleuth?

解决方法

如果您基本上与jpa一起运行整个应用程序,为什么还要运行模拟mvc测试?要么停止使用mockmvc,然后以正常方式启动应用程序,要么需要手动向模拟mvc添加跟踪过滤器