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

如何用Mockito编写Stub模拟响应式栈中的事务操作?

解决响应式事务Mock的NullPointerException问题

问题根源

你当前的Mock代码用buildUserAsMono()创建具体Mono实例作为匹配条件,但每次调用buildUserAsMono()都会生成新的Mono实例,Mockito默认按实例相等匹配,导致Stub条件永远不命中,txOperator.transactional()返回null,最终触发NullPointerException。

正确的Mock实现方式

方式1:通用匹配(推荐)

用参数匹配器any(Mono.class)匹配任意Mono实例,同时通过thenAnswer返回传入的原Mono,保持响应式数据流的一致性:

// 确保txOperator是已初始化的Mock实例(比如通过@Mock注解+MockitoExtension)
Mockito.when(this.txOperator.transactional(Mockito.any(Mono.class)))
       .thenAnswer(invocation -> {
           // 返回调用时传入的Mono参数,模拟事务包装逻辑
           return invocation.getArgument(0);
       });

方式2:精确匹配(按需使用)

如果需要只匹配特定类型的Mono(比如包含User对象的Mono),可以用argThat自定义匹配逻辑:

Mockito.when(this.txOperator.transactional(Mockito.argThat(mono -> {
           // 自定义匹配规则,比如检查Mono是否包含User类型的元素
           return mono.element().blockOptional()
                   .map(elem -> elem instanceof User)
                   .orElse(false);
       })))
       .thenAnswer(invocation -> invocation.getArgument(0));

注意事项

  • 必须确保txOperator是正确Mock的对象:测试类中用@Mock注解标记,并通过@ExtendWith(MockitoExtension.class)或MockitoAnnotations.openMocks(this)完成Mock初始化。
  • 避免用thenReturn(buildUserAsMono()):这种方式会提前生成固定Mono实例,无法模拟真实场景中事务方法对传入Mono的包装逻辑,thenAnswer动态返回传入参数更贴合实际。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:35:04