使用Mockito测试Preferences DataStore的isWizardComplete方法
问题分析
原测试的核心问题是错误地mock了map操作后的Flow,而不是先mockdataStore.data本身。InfoWizardDataSourceImpl初始化时就会基于dataStore.data创建stateFlow,如果dataStore.data没有被正确mock,stateFlow就无法获取到有效数据,导致调用first()时出现异常或返回错误值。
修正方案
- 先mock
dataStore.data,返回一个包含目标Preferences的Flow,用preferencesOf创建携带IS_WIZARD_COMPLETE键值的Preferences实例。 - 确保在测试协程环境中执行挂起函数,使用你自定义的
runCoroutineTest或官方的runTest。
修正后的测试代码
class InfoWizardDataSourceImplTest : BaseCoroutinesTest() { private val dataStore = mock(DataStore::class.java) as DataStore<Preferences> private val infoWizardDataSourceImpl = InfoWizardDataSourceImpl(dataStore) private val IS_WIZARD_COMPLETE = booleanPreferencesKey("isWizardComplete") @Test fun `isWizardComplete returns true when key is set to true`() = runCoroutineTest { // 创建包含指定键值的Preferences实例 val testPreferences = preferencesOf(IS_WIZARD_COMPLETE to true) // mock dataStore.data 返回携带该实例的Flow `when`(dataStore.data).thenReturn(flowOf(testPreferences)) val result = infoWizardDataSourceImpl.isWizardComplete() assertTrue(result) } @Test fun `isWizardComplete returns false when key does not exist`() = runCoroutineTest { // 创建不包含目标键的空Preferences实例 val testPreferences = preferencesOf() `when`(dataStore.data).thenReturn(flowOf(testPreferences)) val result = infoWizardDataSourceImpl.isWizardComplete() assertFalse(result) } }
额外注意事项
- 确保
BaseCoroutinesTest已正确配置测试协程调度器,避免挂起函数执行时出现异常。 - 测试覆盖了两种核心场景:键存在且为true、键不存在(返回默认false),保证方法逻辑的完整性。
内容的提问来源于stack exchange,提问作者TOvchinnikova
相关产品推荐
相关产品推荐

