You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 07:04:06