如何断言Quarkus中返回Uni的方法抛出指定异常?
修复Quarkus Mutiny Uni测试的编译错误及替代测试方案
我来帮你解决这个Mutiny测试的编译问题,同时给你几种可行的测试方案。首先,你遇到的subscribe().withSubscriber()类型参数错误,大概率是因为AssertSubscriber的泛型指定不对,或者导入了错误的Subscriber类。
一、修复编译错误的正确AssertSubscriber用法
首先确保你导入的是Mutiny官方的AssertSubscriber:
import io.smallrye.mutiny.test.AssertSubscriber;
然后编写测试代码时,要给AssertSubscriber指定正确的泛型类型(和你的Uni返回类型一致,也就是User),示例如下:
import io.smallrye.mutiny.test.AssertSubscriber; import org.junit.jupiter.api.Test; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; // 测试类需根据场景添加@QuarkusTest(集成测试)或@ExtendWith(MockitoExtension.class)(单元测试) @Test void testSearchUser_NotFoundThrowsException() { // 模拟userRepository.findById返回null的Uni when(userRepository.findById(anyString())).thenReturn(Uni.createFrom().nullItem()); // 调用待测试方法 Uni<User> userUni = userService.searchUser("invalid-id"); // 订阅并获取AssertSubscriber,这里必须指定<User>泛型 AssertSubscriber<User> subscriber = userUni.subscribe().withSubscriber(AssertSubscriber.create()); // 断言订阅结果:失败且抛出指定异常 subscriber.assertFailed() .assertFailure(BusinessException.class, "你的异常提示信息"); }
为什么之前会报错?如果你的代码里没有给AssertSubscriber指定泛型,或者泛型和Uni的类型不匹配,就会触发类型参数边界错误。Mutiny的AssertSubscriber是泛型类,必须和Uni的发射类型保持一致。
二、更简洁的替代测试方式
如果你觉得手动处理Subscriber太麻烦,还可以用Mutiny的await()方法结合JUnit的断言工具,代码更直观:
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; @Test void testSearchUser_NotFoundThrowsException() { when(userRepository.findById(anyString())).thenReturn(Uni.createFrom().nullItem()); // 使用assertThrows断言异步方法抛出的异常 BusinessException exception = assertThrows(BusinessException.class, () -> userService.searchUser("invalid-id").await().indefinitely()); // 可选:断言异常消息 assertThat(exception.getMessage()).contains("用户不存在"); }
这种方式不需要处理Subscriber,直接通过await().indefinitely()阻塞获取结果(仅在测试环境中推荐使用),然后用JUnit的assertThrows验证异常类型,代码可读性更高。
三、注意事项
- 确保测试类上添加了正确的注解:如果是集成测试,加
@QuarkusTest;如果是单元测试,加@ExtendWith(MockitoExtension.class)并通过@Mock注入userRepository。 - 检查Mutiny依赖版本:Quarkus自带Mutiny,无需单独引入,确保你的Quarkus版本和内置Mutiny版本兼容。
- 避免混淆Subscriber类:不要导入RxJava或其他Reactive库的
AssertSubscriber,必须用io.smallrye.mutiny.test.AssertSubscriber。
内容的提问来源于stack exchange,提问作者Allan Juan
相关产品推荐
相关产品推荐

