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

JUnit测试调用context.getSharedPreferences报空指针问题求助

问题原因

你mock得到的Context实例本身不为空,但你没有为getSharedPreferences方法配置返回规则,Mockito默认对未打桩的对象方法,返回值为null。而Kotlin默认要求SharedPreferences类型的变量为非空,因此在赋值阶段就触发了空安全校验,抛出空指针异常。

解决方案

有两种常用的解决方式:

  • 方案一:使用Mockito为方法打桩
    你可以提前mock出SharedPreferences实例,为Context的对应方法配置返回规则,示例修改如下:

    @Before
    fun setup() {
        context = mock()
        // 打桩配置getSharedPreferences返回值
        val mockSharedPref = mock<SharedPreferences>()
        `when`(context.getSharedPreferences(USER_PREFS, Context.MODE_PRIVATE))
            .thenReturn(mockSharedPref)
        userRepo = UserRepo(context)
    }
    

    配置完成后调用context.getSharedPreferences就会返回你mock的非空实例,测试用例即可正常执行。

  • 方案二:使用Robolectric提供的测试Context
    如果你需要更接近真实运行环境的测试逻辑,不需要手动为Context的各类方法打桩,可以引入Robolectric测试框架,使用它提供的内存级Context,原生支持返回可用的SharedPreferences实例:

    @RunWith(RobolectricTestRunner::class)
    class SharedPrefTest {
        private lateinit var context: Context
        private lateinit var userRepo: UserRepo
        private lateinit var sharedPreferences: SharedPreferences
    
        @Before
        fun setup() {
            // 获取Robolectric提供的应用Context
            context = ApplicationProvider.getApplicationContext()
            userRepo = UserRepo(context)
        }
    
        // 原有测试用例无需修改即可正常运行
        @Test
        fun `check mocked instances are not null`() {
            context assertNotEquals null
            userRepo assertNotEquals null
        }
    
        @Test
        fun `when shared pref instance not null then do further ops`() {
            sharedPreferences = context.getSharedPreferences(USER_PREFS, Context.MODE_PRIVATE)
            sharedPreferences assertNotEquals null
        }
    
        companion object {
            const val USER_PREFS = "userprefs"
        }
    }
    

内容的提问来源于stack exchange,提问作者VVB

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:09:01