Espresso测试Fragment时Mock ViewModel调用doNothing()报错如何解决?
问题解决方法
错误核心原因
- Mockito无返回值方法的打桩语法使用错误,
when块参数结构不符合要求 - Kotlin默认类、方法均为final类型,Mockito默认不支持mock final成员,也会触发该异常
修复步骤
1. 修正doNothing打桩语法
无返回值方法的正确打桩格式为doNothing().when( mock对象 ).方法名(),修改你的打桩代码如下:
// 修正打桩语法 doNothing().`when`(mockVm).getLoginConfig() // 打桩完成后给LiveData赋值 mockVm.loginConfigLiveData.postValue(Resource.Success( LoginConfigResponse( listOf("1"),1,1,"1",true) ))
你原有写法将getLoginConfig()直接传入when的参数中,属于语法错误,Mockito无法识别到要打桩的目标方法。
2. 解决Kotlin final成员无法mock的问题
二选一即可:
- 方案A:修改业务代码加open修饰
给需要mock的ViewModel类和getLoginConfig方法加上open修饰:open class SplashVM : ViewModel() { // 方法也加open open fun getLoginConfig() { viewModelScope.launchApiWith(_loginConfigLiveData) { repository.getLoginConfig() } } } - 方案B:开启Mockito inline mock支持(无需修改业务代码)
第一种方式是添加Mockito inline依赖:
第二种方式是在测试资源目录下新建// 单元测试用 testImplementation "org.mockito:mockito-inline:4.8.1" // Espresso Instrumented测试用 androidTestImplementation "org.mockito:mockito-inline:4.8.1"resources/mockito-extensions/org.mockito.plugins.MockMaker文件,写入内容:mock-maker-inline
3. 补充适配
如果ViewModel中的loginConfigLiveData是私有可变属性对外仅暴露不可变LiveData,需要将该属性也加open修饰,或者提供测试可用的setter方法,避免赋值失败。
内容的提问来源于stack exchange,提问作者milad salimi
相关产品推荐
相关产品推荐

