如何测试Quarkus框架中Mutiny实现的轮询模式?
错误根因
- 你返回的Multi是通过
.indefinitely()生成的无限流,永远不会触发完成事件,你调用assertCompleted()会持续等待直到超时 - 代码中硬编码了3秒的轮询延迟,第一次数据返回前就会触发测试的默认超时阈值
修复方案
第一步:将轮询间隔改为可配置(可选但推荐)
避免测试时无意义等待3秒,把延迟参数从硬编码改成配置注入:
在生产环境的application.properties添加配置:
scheduler.poll-interval=3s
修改业务代码:
@ApplicationScoped public class ExampleScheduler { @Inject @RestClient ExampleService service; @ConfigProperty(name = "scheduler.poll-interval") Duration pollInterval; @PostConstruct void init() { pollSource(); } @Outgoing("sensor_data_out") Multi<String> pollSource() { Uni<String> stream = service.getString() .runSubscriptionOn(Infrastructure.getDefaultExecutor()); return stream.repeat().withDelay(pollInterval) .indefinitely(); } }
第二步:修正测试逻辑
测试时将轮询间隔设置为0,同时不要等待流完成,仅验证收到指定数量的元素即可:
@QuarkusTest @TestPropertySource(properties = "scheduler.poll-interval=0") class ExampleSchedulerTest { @Inject ExampleScheduler classToTest; @InjectMock ExampleService mockService; @BeforeEach void setUp() { when(mockService.getString()).thenReturn(Uni.createFrom().item("ANSWER")); } @Test void pollSource() { final Multi<String> stream = classToTest.pollSource(); // 声明要消费2个元素,验证轮询重复逻辑生效 AssertSubscriber<String> subscriber = stream.subscribe().withSubscriber(AssertSubscriber.create(2)); // 等待2个元素接收完成,不需要等无限流结束 subscriber.awaitNextItems(2) .assertItems("ANSWER", "ANSWER"); // 测试结束主动取消订阅,避免后台线程一直运行 subscriber.cancel(); } }
内容的提问来源于stack exchange,提问作者Schallabajzer
相关产品推荐
相关产品推荐

