
本文介绍在 quarkus + mutiny 项目中,如何正确编写单元测试来验证 `uni
在基于 Mutiny 的响应式应用(如 Quarkus)中,Uni 是处理单个异步结果的核心类型。当业务逻辑需在数据缺失时主动抛出异常(例如 BusinessException),测试该异常是否被正确触发至关重要。但直接复用 Multi 的 AssertSubscriber 会导致编译错误——因为 Uni 和 Multi 的订阅器接口不兼容:UniSubscriber 与 MultiSubscriber 是不同泛型契约,AssertSubscriber 专为 Multi 设计,无法安全用于 Uni。
✅ 正确做法是使用 Mutiny 官方提供的 UniAssertSubscriber(位于 io.smallrye.mutiny:test-utils 模块)。它专为 Uni 设计,支持类型安全的失败断言。
首先,确保已引入测试依赖(Maven):
io.smallrye.reactive mutiny-test-utils test
然后,修正测试代码如下:
@Test
public void shouldThrowAnErrorWhenUserIsNotFound() {
// 模拟仓库返回 nullItem,触发 map 中的异常分支
Mockito.when(userRepository.findById(Mockito.any()))
.thenReturn(Uni.createFrom().nullItem());
service.searchUser(new ObjectId())
.subscribe()
.withSubscriber(UniAssertSubscriber.create()) // ✅ 使用 UniAssertSubscriber
.assertFailedWith(BusinessException.class, "Could not find an user with the given id.");
}⚠️ 注意事项:
- 不要手动声明 AssertSubscriber 变量(如 AssertSubscriber subscriber = ...),这会干扰泛型推导;
- 必须调用 .withSubscriber(UniAssertSubscriber.create()),而非 AssertSubscriber.create();
- assertFailedWith(Class, String) 同时校验异常类型与消息内容,增强测试可靠性;
- 若只需校验异常类型,可使用 assertFailedWith(BusinessException.class);
- 确保 BusinessException 是运行时异常(RuntimeException 子类),否则 Mutiny 默认不会将其作为“失败事件”传播(而是包装为 UniOnFailure 行为)。
? 小结:Uni 的测试必须匹配其专属订阅器工具。UniAssertSubscriber 提供了类型安全、链式流畅的断言 API,是验证异常路径的首选方案。避免混用 Multi 工具类,可彻底规避泛型绑定错误,并提升测试可维护性与准确性。









