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

Mockito如何模拟参数和返回值均为Mono<>类型的方法?

解决Mockito模拟Mono参数方法的严格存根匹配问题

问题原因

Mockito默认通过对象的equals()方法匹配方法参数,但每次调用Mono.just("TEXT")都会生成全新的Mono实例——即使内部包裹的字符串内容相同,对象引用也不一样。这就导致存根时的参数和实际调用时的参数被Mockito判定为不匹配,触发Strict Stubbing的参数不匹配错误。

解决方案

推荐以下几种可行的处理方式:

  • 使用通用参数匹配器
    如果不需要精确匹配Mono中的内容,直接用any(Mono.class)匹配任意Mono类型参数:

    when(myService.get(any(Mono.class))).thenReturn(Mono.just(new BusinessObject("blabla")));
    
  • 使用自定义参数匹配器精确匹配内容
    如果需要验证Mono包裹的具体值,用argThat结合Lambda表达式判断Mono内的内容:

    when(myService.get(argThat(mono -> {
        try {
            return "TEXT".equals(mono.block());
        } catch (Exception e) {
            return false;
        }
    }))).thenReturn(Mono.just(new BusinessObject("blabla")));
    

    (注:测试场景下使用block()是安全的,不会影响生产代码的反应式特性)

  • 复用同一个Mono实例
    提前创建Mono实例,确保存根和实际调用时传入的是同一个对象:

    Mono<String> testMono = Mono.just("TEXT");
    when(myService.get(testMono)).thenReturn(Mono.just(new BusinessObject("blabla")));
    // 需保证业务代码中调用myService.get时传入的是上述testMono实例
    

    这种方式灵活性较低,仅适用于业务代码参数可控的场景。

  • 临时关闭Strict Stubbing模式(不推荐)
    如果只是临时绕过Strict检查,可以在创建Mock时设置宽松模式:

    MyService myService = mock(MyService.class, withSettings().strictness(Strictness.LENIENT));
    

    或者在测试类上添加注解:

    @MockitoSettings(strictness = Strictness.LENIENT)
    

    不推荐长期使用,因为Strict模式能帮助提前发现参数不匹配的潜在问题。

内容的提问来源于stack exchange,提问作者psv

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:02:12