Spring WebFlux:测试返回1秒间隔Flux的RestController遇阻
嘿,我太懂你这种烦恼了——写返回1秒间隔Flux的WebFlux控制器测试时,总是差那么一步就成功,但就是卡壳对吧?毕竟浏览器访问正常,说明业务逻辑没问题,就是测试里的时间控制和流处理没摸透。我来给你梳理几个实用的解决方案,帮你搞定这个测试:
针对1秒间隔Flux的WebFlux控制器测试方案
1. 用WebTestClient + StepVerifier虚拟时间(最省心)
WebTestClient是WebFlux测试的标配,搭配StepVerifier的虚拟时间功能,完全不用真的等1秒来验证每一条数据,既快又稳定。
举个具体的测试代码例子,假设你的控制器端点是/,返回每秒一条的Flux:
@WebFluxTest(YourStreamController.class) class FluxStreamControllerTest { @Autowired private WebTestClient webTestClient; @Test void test1SecondIntervalStream() { webTestClient.get().uri("/") .exchange() .expectStatus().isOk() .returnResult(String.class) .getResponseBody() .as(StepVerifier::create) .thenAwait(Duration.ofSeconds(3)) // 虚拟等待3秒,应该收到3条数据 .expectNextCount(3) .thenCancel() // 一定要取消流,不然测试会一直跑下去超时 .verify(); } }
这里的核心是thenAwait用的是虚拟时间,不是真实等待,测试瞬间就能跑完。
2. 把服务里的调度器抽出来(更可控)
如果你的服务代码里直接写死了Flux.interval(Duration.ofSeconds(1)),测试时虚拟时间可能不起作用——因为默认调度器绑定的是真实线程。这时候把调度器抽成可注入的,测试时替换成虚拟调度器就搞定了:
先改造服务类:
@Service public class YourStreamService { private final Scheduler scheduler; // 构造注入调度器,生产环境用默认的,测试用虚拟的 public YourStreamService(Scheduler scheduler) { this.scheduler = scheduler; } public Flux<String> getIntervalStream() { return Flux.interval(Duration.ofSeconds(1), scheduler) .map(index -> "Message " + index); } }
然后测试时用虚拟时间来控制:
@WebFluxTest(YourStreamController.class) class FluxStreamControllerTest { @Autowired private WebTestClient webTestClient; @Test void testStreamWithControlledTime() { StepVerifier.withVirtualTime(() -> webTestClient.get().uri("/") .exchange() .expectStatus().isOk() .returnResult(String.class) .getResponseBody()) .expectSubscription() .thenAwait(Duration.ofSeconds(2)) .expectNext("Message 0", "Message 1") // 验证前两条数据 .thenCancel() .verify(); } // 测试配置类,注入虚拟调度器 @TestConfiguration static class TestConfig { @Bean public Scheduler testScheduler() { return Schedulers.immediate(); // 配合虚拟时间使用,让流立即发射数据 } } }
这样测试完全摆脱真实时间的限制,想验证几条数据就虚拟等待几秒,精准又高效。
3. 踩过的坑给你提个醒
- 别忘了取消流:测试里一定要加
thenCancel(),不然Flux会一直发射数据,直接导致测试超时失败。 - 别用真实时间等待:如果测试里写
Thread.sleep(3000),不仅慢得离谱,还容易因为CI环境的性能波动导致测试不稳定。 - 调度器必须可替换:如果服务里的Flux用了默认调度器,StepVerifier的虚拟时间会失效,因为默认调度器是跑在真实线程池里的。
内容的提问来源于stack exchange,提问作者Reenactor Rob
相关产品推荐
相关产品推荐

