Vert.x 4单元测试中如何模拟时间流逝?求可行方案
Vert.x 4 模拟时间流逝的实现方案
Vert.x 4 完全支持在单元测试中模拟时间流逝,只是实现逻辑和 Vert.x 3 有所区别——核心是使用TestVertx(测试套件提供的专用 Vertx 实例)来替代普通 Vertx 实例,它内置了可手动控制的测试时钟。
核心 Vertx API 模拟时间示例
如果你的代码使用 Vert.x 核心 API(比如 setTimer、setPeriodic),直接用 TestVertx 创建实例并操作其内置的 TestClock 即可:
@Test void simulateCoreVertxTimeFlow(VertxTestContext testContext) { // 创建带可控制时钟的测试Vertx实例 TestVertx testVertx = TestVertx.create(); Vertx vertx = testVertx.vertx(); // 设置5秒后触发的定时器 vertx.setTimer(5000, id -> { testContext.completeNow(); }); // 直接推进测试时钟5秒,无需等待实际时间 testVertx.clock().advanceTime(5, TimeUnit.SECONDS); // 等待测试完成 testContext.awaitCompletion(5000, TimeUnit.MILLISECONDS); }
RxJava Vertx API 兼容方案
如果你的代码基于 RxJava 绑定的 Vertx API,RxHelper.scheduler(vertx) 依然有效,但需要确保使用的是 TestVertx 创建的实例——此时 TestScheduler 和 TestClock 会自动同步时间,两种方式推进时间都可以:
@Test void simulateRxVertxTimeFlow(VertxTestContext testContext) { TestVertx testVertx = TestVertx.create(); Vertx vertx = testVertx.vertx(); TestScheduler testScheduler = RxHelper.scheduler(vertx); // RxJava延迟任务 Single.timer(5, TimeUnit.SECONDS, testScheduler) .subscribe(__ -> testContext.completeNow()); // 两种推进时间的方式二选一即可 testScheduler.advanceTimeBy(5, TimeUnit.SECONDS); // 或者 testVertx.clock().advanceTime(5, TimeUnit.SECONDS); testContext.awaitCompletion(5000, TimeUnit.MILLISECONDS); }
为什么 Vert.x 3 的方法不再生效?
Vert.x 4 重构了时间控制逻辑,将核心 Vertx 实例的时钟与 RxJava 调度器解耦:
- 原 Vert.x 3 中
RxHelper.scheduler(vertx)会直接绑定 Vertx 内部时钟,因此能控制核心 API 的时间; - Vert.x 4 中该调度器仅对 RxJava 绑定的 API 生效,核心 Vertx 实例的时钟必须通过 TestVertx 提供的
TestClock来控制,这也是为什么你找不到VertxOptions.setClock()方法——TestVertx 已经封装了这个能力。
依赖说明
需要确保引入 Vert.x 测试依赖(以 JUnit 5 为例):
<dependency> <groupId>io.vertx</groupId> <artifactId>vertx-junit5</artifactId> <version>${vertx.version}</version> <scope>test</scope> </dependency>
内容的提问来源于stack exchange,提问作者Ryszard Rodzynka
相关产品推荐
相关产品推荐

