You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:15:08