问题描述
我们有一个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添加跟踪过滤器