使用Mockito无法mock对应方法,调用后返回的record变量始终为null
问题根因
以下是record返回null的常见原因:
- Kotlin函数类型参数匹配失败:你调用的
getTransLockDbRecord方法第二个参数是Kotlin函数类型(也就是代码里的Lambda表达式),Mockito默认的any()匹配规则没有适配Kotlin语法,无法正确识别匹配该函数类型参数,导致你写的mock桩不生效,方法调用时走了真实逻辑返回null。 - Mock实例未注入到业务逻辑:你只声明了
lockDatabaseRecordService的mock对象,但是没有把这个mock实例替换掉业务代码里实际依赖的service实例,业务代码还是调用的真实service的方法,自然无法返回你预设的mock对象。 - 参数匹配不通过:你桩代码里用
eq(dbRecordId)匹配第一个参数,如果业务代码实际执行时传入的id和你测试类里生成的dbRecordId不一致,匹配规则不触发,mock也不会生效返回null。
解决方法
- 适配Kotlin参数匹配规则
优先引入mockito-kotlin依赖适配Kotlin语法,修改桩代码,明确指定第二个参数的匹配类型为对应函数类型:
// 明确匹配函数类型参数 `when`(lockDatabaseRecordService.getTransLockDbRecord(eq(dbRecordId), any<(LockDatabaseRecord) -> Int>())).thenReturn(lockDatabaseRecord)
如果暂时不想引入额外依赖,也可以手动关闭Mockito的非空校验,或者用anyOrNull()替代any()。
2. 确保mock实例正确注入
如果用注解方式测试,给你要测试的业务类加@InjectMocks注解,给lockDatabaseRecordService加@Mock注解,Mockito会自动完成注入;如果是手动实例化业务类,在构造时传入你mock好的lockDatabaseRecordService实例即可。
3. 排查参数匹配问题
可以先把第一个参数的匹配规则改成any<UUID>(),测试是否能返回你mock的lockDatabaseRecord对象,如果可以就说明你业务代码实际传入的id和测试类生成的id不一致,调整参数保证两者相同即可。
内容的提问来源于stack exchange,提问作者mengmeng
相关产品推荐
相关产品推荐

