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

如何将Reactor框架切换为完全同步模式以解决mvcMock集成测试问题

问题解决方案

一、将Reactor切换为全同步执行模式

可以通过Reactor提供的全局调度器工厂钩子,将所有内置调度器替换为Schedulers.immediate(),所有异步逻辑都会在调用线程同步执行,无线程切换:

  1. 测试前置配置(添加到测试类的初始化逻辑中,比如@BeforeEach标注的方法):
import reactor.core.scheduler.Schedulers;

// 替换所有调度器为同步即时调度
Schedulers.setFactory(new Schedulers.Factory() {
    @Override
    public Scheduler newBoundedElastic(int threadCap, int queuedTaskCap, String name, int ttlSeconds) {
        return Schedulers.immediate();
    }

    @Override
    public Scheduler newParallel(int parallelism, String name) {
        return Schedulers.immediate();
    }

    @Override
    public Scheduler newSingle(String name) {
        return Schedulers.immediate();
    }
});
  1. 测试结束后重置调度器工厂,避免影响其他测试:
// 放在@AfterEach标注的方法中
Schedulers.resetFactory();

注意:如果业务逻辑中存在手动创建线程、未通过Reactor调度器执行的代码,该方案无法覆盖这部分异步逻辑。

二、基于MockMvc编写集成测试

完成上述同步配置后,controller接口调用subscribe()时会同步执行完所有service.compute的逻辑,无需额外等待,直接按常规MockMvc流程编写测试即可:

  1. 常规MockMvc请求构造:
mockMvc.perform(post("/path/full")
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(testRequest)))
        .andExpect(status().isOk());
  1. 请求执行完成后直接断言业务结果,比如校验数据库存储结果、下游依赖调用情况、缓存变更等:
// 校验业务执行结果
assertThat(orderService.queryStatus(testRequest.getOrderId())).isEqualTo(COMPUTED);
// 如果用Mock的Service层,也可以直接校验方法调用
verify(service, times(1)).compute(any(DTO.class));

如果业务存在未通过Reactor调度器的异步逻辑,可以引入Awaitility做轮询断言:

import org.awaitility.Awaitility;
import java.time.Duration;

Awaitility.await()
        .atMost(Duration.ofSeconds(3))
        .untilAsserted(() -> assertThat(orderService.queryStatus(testRequest.getOrderId())).isEqualTo(COMPUTED));

额外优化建议

当前controller直接调用subscribe()的写法存在风险:异步逻辑抛出的异常无法被Spring MVC全局异常处理器捕获,应用关闭时未执行完的异步任务会直接中断丢失。可以将接口返回值改为Mono<Void>,Spring MVC原生支持Reactor类型返回值,会自动处理订阅、异常传递、生命周期绑定:

@PostMapping(path = "/path/full")
public Mono<Void> compute(@RequestBody @Validated @JsonView DTO request) throws Exception {
    return service.compute(request);
}

内容的提问来源于stack exchange,提问作者Praytic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 03:36:03