Junit测试SharedPreferences存储数据后断言失败问题排查求助
核心错误点
- 仅定义mock行为,未实际执行存储操作
whenever(editor.putString(xxx))只是定义mock Editor对象调用putString时的返回值规则,不会真的执行存储逻辑,需要主动调用editor.putString()方法才会触发存储流程。 - 存储的Key参数错误
putString第一个参数传的是USER_PREFS(这是SharedPreference的配置文件名),但后续校验是否存在用的是USER_ID_KEY,两者不匹配,就算存成功也查询不到对应值。 - 未提交编辑结果
调用putString后必须主动调用apply()/commit()才能将修改同步到SharedPreference中,原代码没有执行提交操作。 - mock对象未定义
contains方法的返回规则(若使用纯Mockito mock)
如果用的是Mockito mock出来的userPrefs对象,没有为userPrefs.contains(USER_ID_KEY)打桩的话,该方法默认返回布尔类型默认值false,也会导致断言失败。这类状态读写场景更推荐使用AndroidX测试库提供的真实可读写的SharedPreferences实现,而非全mock。
修复代码示例
推荐方案:使用真实测试用SharedPreference
@Test fun `when store user then load user`() { // 使用AndroidX测试库提供的真实可读写SharedPreferences实例 val userPrefs = SharedPreferences.Builder() .withName(USER_PREFS) .build() val editor = userPrefs.edit() val user = getUser() // 主动执行存储+提交操作 editor.putString(USER_ID_KEY, user!!.userID) editor.apply() // 断言正常通过 assert(userPrefs.contains(USER_ID_KEY)) }
兼容全mock场景方案
如果必须使用全mock验证调用流程,修复如下:
@Test fun `when store user then load user`() { whenever(context.getSharedPreferences(USER_PREFS, Context.MODE_PRIVATE)).thenReturn(userPrefs) whenever(userPrefs.edit()).thenReturn(editor) whenever(editor.putString(anyString(), anyString())).thenReturn(editor) doNothing().`when`(editor).apply() // 为contains方法打桩模拟存储后的状态 whenever(userPrefs.contains(USER_ID_KEY)).thenReturn(true) val user = getUser() // 主动执行存储+提交操作 editor.putString(USER_ID_KEY, user!!.userID) editor.apply() assert(userPrefs.contains(USER_ID_KEY)) }
全mock方案无法验证真实的存储逻辑,仅能验证方法调用流程是否符合预期,不推荐用于读写逻辑校验。
内容的提问来源于stack exchange,提问作者VVB
相关产品推荐
相关产品推荐

