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

如何断言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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:05:23