Mockito调用真实方法时方法未mock、内部依赖为空等问题如何解决
Mockito 单元测试指定方法Mock、其余走真实逻辑解决方案
错误写法根因
- 第一种写法:
@Mock注解优先级高于手动初始化的mock实例,你手动指定的CALLS_REAL_METHODS配置被@Mock默认行为覆盖,因此所有方法默认走mock逻辑不会调用真实实现。 - 第二种写法:Spy实例的stub使用
when().thenReturn()语法会先触发一次真实方法的调用,如果该方法内部有依赖逻辑就会执行失败,看起来像无法mock,属于Spy stub的语法使用错误。 - 第三种写法:被
@Mock修饰的FrontSecurityService实例本身的成员字段不会自动绑定你声明的@Mock MenService,调用真实方法时内部依赖自然为null。
正确实现方案
直接使用@Spy初始化待测试类实例,构造函数传入所有mock好的依赖,修改stub语法即可:
完整代码示例
@RunWith(MockitoJUnitRunner.class) public class FrontSecurityServiceTest { // 先mock所有依赖的服务 @Mock PerService perService; @Mock MenService menService; // Spy初始化待测试类,构造函数传入mock好的依赖,保证内部依赖不为空 @Spy private FrontSecurityService frontSecurityService = new FrontOfficeSecurityService(perService, menService); @Test public void testCheckIfHold() { // 先stub依赖服务的返回 MenReturn menReturn1 = MenReturn.builder().build(); when(menService.getMen(anyString(), anyLong())).thenReturn(Arrays.asList(menReturn1)); // Spy实例的stub用doReturn语法,不会触发真实方法调用 doReturn("000").when(frontSecurityService).getLoggedInUserId(); // 调用方法,默认走真实逻辑,内部依赖都是mock好的实例 frontSecurityService.checkIfHold(9L); // 补充你的断言逻辑 } }
核心规则说明
- Spy实例默认所有方法走真实逻辑,只有被stub的方法会返回mock值,完全符合需求
- Spy对象stub必须优先使用
doReturn|doThrow|doAnswer开头的语法,避免触发真实方法执行 - 构造Spy实例时传入所有mock好的依赖,不需要额外处理注入,内部调用时依赖自然可用
内容的提问来源于stack exchange,提问作者Nunyet Calçada
相关产品推荐
相关产品推荐

