Mockito如何为带构造参数的Mock传参实现部分Mock调用真实方法
问题根因
你当前的写法不生效,是因为mock(Channel.class)生成的是纯Mock代理对象,不会执行Channel类的构造逻辑,构造方法要求传入的端口参数不会被赋值到实例字段上,字段会保留类型默认值(数值类型默认0,引用类型默认null)。这种情况下即使配置thenCallRealMethod()调用真实的connect方法,方法内部读取到的端口也是无效值,无法正常运行。
实现方式
选以下任意一种即可实现需求,两种方式生成的实例都会持有构造传入的端口参数,保证真实方法执行时状态正确:
方式一:用
Spy做部分Mock(官方推荐方案)
Spy是Mockito专门为部分Mock场景设计的API,本质是对真实实例的代理,会完整保留实例构造后的所有状态,默认所有方法都走真实实现,你只需要给需要替换逻辑的方法单独打桩即可,不需要额外给connect配置thenCallRealMethod()。
手动写法示例:// 构造时传入你实际需要的端口参数,比如示例里的8080 Channel chan = spy(new Channel(8080)); // 仅Mock需要替换实现的handle方法 when(chan.handle()).thenReturn("Ok"); // 直接调用chan.connect()就会执行真实逻辑,自动使用构造传入的端口参数如果用注解写单测,直接初始化带参实例加
@Spy即可:@Spy private Channel chan = new Channel(8080);方式二:创建Mock时指定构造参数+默认真实调用
如果不想用Spy,也可以在创建Mock时修改默认配置,让Mock实例执行带参构造,同时默认调用真实方法:Channel chan = mock(Channel.class, withSettings() .useConstructor(8080) // 传入构造需要的端口参数 .defaultAnswer(CALLS_REAL_METHODS) // 未打桩的方法默认走真实实现 ); when(chan.handle()).thenReturn("Ok");
小提示
如果要打桩的方法是void返回类型,或者打桩阶段不想触发原方法的执行逻辑(比如原方法会发起真实网络请求产生副作用),建议用doReturn语法打桩,避免Spy默认执行真实方法导致异常:
doReturn("Ok").when(chan).handle();
内容的提问来源于stack exchange,提问作者paul
相关产品推荐
相关产品推荐

