添加@SpringBootTest后StepVerifier无法识别异步写入的上下文
解决思路与方案
原因
@SpringBootTest会自动启用Reactor上下文传播机制(由ReactorTestAutoConfiguration配置),该机制将Reactor上下文与Spring请求上下文绑定,严格遵循Reactor上下文向下传播、不反向回流的规则:
- 原代码中
contextWrite挂在flatMap内部的子Mono(Mono.just(2))上,这个上下文仅属于子Mono的局部上下文,不会传递到父Mono序列 - 未加
@SpringBootTest时,StepVerifier的上下文捕获逻辑可以“穿透”到子Mono;但启用上下文传播后,StepVerifier只能捕获整个序列的根上下文,无法获取子Mono的局部上下文
方案1:调整contextWrite的位置(推荐)
把contextWrite移到flatMap外部,确保上下文被注入到整个序列的根上下文中,后续所有操作都能访问到:
修正后的测试代码
@SpringBootTest public class FooTest { @Test void test() { StepVerifier.create(Mono.just(1) .flatMap(a -> Mono.just(2)) .contextWrite(ctx -> ctx.put("foo", "boo"))) .expectNext(2) .expectAccessibleContext() .contains("foo", "boo") .verifyComplete(); } }
对应WebFilter的修正代码
@Component @Order(105) public class EntitlementsFilter implements WebFilter { @Override @NonNull public Mono<Void> filter(ServerWebExchange exchange, @NonNull WebFilterChain chain) { return service.getAuthorization() // 先执行flatMap获取chain的结果 .flatMap(authorization -> chain.filter(exchange)) // 再给整个流写入上下文 .contextWrite(ctx -> ctx.put("authorization", authorization)); } }
方案2:禁用Reactor上下文传播(仅调试用)
如果必须保留原有代码结构,可以在测试类中排除自动配置类来禁用上下文传播:
@SpringBootTest(exclude = ReactorTestAutoConfiguration.class) public class FooTest { // 原有测试代码不变 }
内容的提问来源于stack exchange,提问作者Jakub
相关产品推荐
相关产品推荐

