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

Mockito测试RxJava含FlatMap的代码时无法进入FlatMap内部如何解决

问题原因
  • Mockito注解未生效。如果测试类没有添加Mockito的运行器/扩展注解(Junit4加@RunWith(MockitoJUnitRunner.class),Junit5加@ExtendWith(MockitoExtension.class)),@Mock标注的objectResolver不会被实例化,默认是null。当流执行到flatMap内部调用objectResolver.resolve时直接抛出空指针异常,流直接进入onError终止,自然不会执行后续逻辑,且当前测试代码没有捕获错误,只会收到测试失败结果,看不到具体异常。
  • 参数匹配与Stub不匹配。你测试中传入toTest方法的是new Object(),如果代码中的Object是Java自带的java.lang.Object而非自定义业务类,它根本没有getField()、getAnotherField()方法,调用时会直接抛出异常;就算是自定义类,若getField()返回的参数和Stub时的any()匹配规则冲突(比如方法参数是基本类型但any()匹配的是包装类型),也会导致Stub不生效,resolve方法返回null或者默认值,触发空指针。
  • 测试代码语法错误。你提供的测试代码中when(objectResolver.resolve(any()).thenReturn(Mono.just(new ResolvedObject()))缺少右括号,正确写法是when(objectResolver.resolve(any())).thenReturn(Mono.just(new ResolvedObject())),语法错误会导致Stub设置失败。
  • 若你Stub返回的new ResolvedObject()的getField()返回值、传入toTest的业务对象的getAnotherField()返回值拼接后和期望的"resultString"不一致,也会导致测试失败,但这种情况是进入了flatMap逻辑只是结果不对,不符合无法进入内部的现象。
解决步骤
  • 给测试类添加Mockito启动注解
    Junit4示例:
    @RunWith(MockitoJUnitRunner.class)
    public class CodeTest {
        // 测试代码
    }
    
    Junit5示例:
    @ExtendWith(MockitoExtension.class)
    public class CodeTest {
        // 测试代码
    }
    
  • 修正测试代码的语法错误,同时明确参数匹配规则,确认参数匹配没问题可以用any(),否则用具体的参数值匹配:
    when(objectResolver.resolve(any())).thenReturn(Mono.just(new ResolvedObject()));
    
  • 使用自定义的业务对象作为入参,不要和java.lang.Object重名避免歧义,同时给测试用到的字段设置明确的返回值,避免空指针:
    示例:
    // 假设自定义业务类叫BizObject,不要叫Object避免冲突
    BizObject testObj = new BizObject();
    testObj.setField("testField");
    testObj.setAnotherField("anotherField");
    
    ResolvedObject resolvedObject = new ResolvedObject();
    resolvedObject.setField("resolvedField");
    when(objectResolver.resolve(eq("testField"))).thenReturn(Mono.just(resolvedObject));
    
  • 调整测试代码,先开启错误日志或者添加expectError排查异常,确认问题后再校验结果:
    排查阶段可以这么写查看具体报错:
    StepVerifier.create(code.toTest(testObj))
        .consumeErrorWith(Throwable::printStackTrace)
        .verify();
    
    确认无异常后再改成你需要的校验逻辑:
    StepVerifier.create(code.toTest(testObj))
        .expectNext("resolvedFieldanotherField") // 和实际拼接的结果保持一致
        .verifyComplete();
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:24:02