Android SharedPreferences测试:验证值存储正确性的问题
问题分析与解决方案
你的测试代码之所以不生效,核心原因是Mock对象不会自动维护状态——你mock了SharedPreferences和Editor,但没有正确配置它们之间的交互逻辑,也没有验证代码的调用行为。
问题拆解
- 你只设置了
sharedPreferences.edit()返回mockEditor,但没有处理Editor的链式调用(putString()之后需要返回自身才能继续调用apply())。 - Mock的
SharedPreferences不会自动存储你通过putString()传入的值,所以直接调用getString()会返回默认的null,断言自然失败。 - 测试
SharedPreferences的保存逻辑,重点应该是验证代码是否正确调用了Editor的方法,而不是测试SharedPreferences本身的存储能力(那是Android系统的职责)。
修正后的测试代码
// 1. Mock所需对象 val mockSharedPreferences = mock(SharedPreferences::class.java) val mockEditor = mock(SharedPreferences.Editor::class.java) // 2. 配置Editor的链式调用:putString方法返回自身,支持后续调用apply() `when`(mockEditor.putString(anyString(), anyString())).thenReturn(mockEditor) // 3. 配置SharedPreferences的edit()返回mockEditor `when`(mockSharedPreferences.edit()).thenReturn(mockEditor) // 4. 执行你的保存逻辑(这里假设你的保存逻辑需要传入mockSharedPreferences) with(mockSharedPreferences.edit()) { putString("testkey", "dummyValue") apply() } // 5. 验证关键交互:确认putString被传入了正确的key和value verify(mockEditor).putString("testkey", "dummyValue") // 6. 验证apply()方法被调用(确保提交了编辑) verify(mockEditor).apply()
额外说明
如果你确实想模拟SharedPreferences的“存储”行为(比如调用getString能返回之前put的值),可以用spy而不是mock,或者手动维护一个存储映射:
// 用spy模拟真实的SharedPreferences行为(需要Android上下文,适合Instrumented Test) val sharedPreferences = spy(PreferenceManager.getDefaultSharedPreferences(context)) // 执行保存逻辑 with(sharedPreferences.edit()) { putString("testkey", "dummyValue") apply() } // 断言存储结果 assert(sharedPreferences.getString("testkey", null) == "dummyValue")
不过单元测试中,验证调用行为的方式更纯粹,也更符合Mock的设计思想——我们只需要确认自己的代码正确调用了系统API即可,无需重复测试系统功能。
内容的提问来源于stack exchange,提问作者Rgfvfk Iff
相关产品推荐
相关产品推荐

