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

如何使用StepVerifier稳定测试Redis infinite stream监听方法

问题根因

测试不稳定的核心原因是StreamReceiver的订阅是异步IO操作:调用streamFromLatest方法触发订阅后,StreamReceiver需要和Redis完成网络交互、注册监听、定位到latest偏移量,整个过程需要几十到几百毫秒不等。
原测试代码中StepVerifier的.then()回调会在订阅触发后立即执行,此时大概率还没完成Redis侧的订阅注册,写入的消息会被StreamOffset.latest策略跳过(只会消费订阅完成之后新增的消息)。Maven运行时测试执行速度更快,订阅未完成就发消息的概率为100%,因此必败;Eclipse运行时偶尔初始化速度够快,所以会偶发成功。

解决方案

完全可以通过调整StepVerifier逻辑实现稳定测试,不需要修改业务代码,推荐两种可行方案:

方案1:增加初始化等待(适配90%以上场景)

在发送消息前增加固定时长的等待,给StreamReceiver留够初始化时间,修改后的测试代码如下:

@Autowired 
private ClassUnderTest template;

// 优先用原生ReactiveStringRedisTemplate,避免SpyBean代理增加延迟
@Autowired
private ReactiveStringRedisTemplate reactiveStringRedisTemplate;

@Test
void streamFromLatest() {
    final ConfigurationRedis configRedis = ...;

    StepVerifier.create(template.streamFromLatest(streamKey))
        .expectNextCount(0)
        // 等待500ms确保订阅初始化完成,可根据CI环境性能调整时长
        .thenAwait(Duration.ofMillis(500))
        .then(() ->
            reactiveStringRedisTemplate
                .opsForStream()
                .add(StreamRecords.objectBacked(configRedis).withStreamKey(streamKey))
                .block())
        .expectNext(configRedis)
        .thenCancel()
        .verify(Duration.ofSeconds(20));
}

方案2:重试发送消息(适配性能波动大的CI环境)

如果CI环境性能波动大,固定等待仍偶发失败,可以采用重试发送逻辑,确保订阅完成后消息能被接收到:

@Test
void streamFromLatest() {
    final ConfigurationRedis configRedis = ...;

    StepVerifier.create(template.streamFromLatest(streamKey))
        .expectNextCount(0)
        .then(() ->
            // 最多重试3次发送,每次间隔300ms
            Mono.defer(() -> reactiveStringRedisTemplate
                .opsForStream()
                .add(StreamRecords.objectBacked(configRedis).withStreamKey(streamKey))
            )
            .retryBackoff(3, Duration.ofMillis(300))
            .block()
        )
        .expectNextMatches(configRedis::equals)
        .thenCancel()
        .verify(Duration.ofSeconds(20));
}
额外优化建议
  • 给Redis Testcontainers增加健康检测,确保Redis服务完全启动后再执行测试,避免网络波动影响
  • 如果业务允许,可以给StreamReceiver增加订阅完成的回调钩子,测试时监听该钩子再触发消息发送,可完全消除无效等待时间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 09:39:03