如何为DataStore的存储与读取方法编写单元测试用例
DataStore Preferences 单元测试实现方案
一、优化实现类(提升可测试性)
原实现依赖Context和DI框架,不利于单元测试。建议将DataStore作为构造参数传入,降低耦合:
interface TestDataSource { suspend fun setTestFlag(flag: Boolean) suspend fun getTestFlag(): Flow<Boolean?> } class TestDataSourceImpl( private val dataStore: DataStore<Preferences> ) : TestDataSource { companion object { val testFlag = booleanPreferencesKey("testKey") } override suspend fun setTestFlag(flag: Boolean) { dataStore.edit { it[testFlag] = flag } } override suspend fun getTestFlag(): Flow<Boolean?> { // 简化原实现,直接返回map后的Flow即可 return dataStore.data.map { it[testFlag] } } }
生产环境中通过DI模块提供实例(以Koin为例):
val dataSourceModule = module { single<TestDataSource> { TestDataSourceImpl(get<Context>().dataStore) } }
二、添加测试依赖
在模块级build.gradle.kts中添加测试所需依赖:
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3") testImplementation("androidx.datastore:datastore-preferences-testing:1.0.0")
三、编写单元测试用例
使用TestPreferencesDataStore创建内存级DataStore,避免真实文件IO,结合runTest处理协程测试:
import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.testing.TestPreferencesDataStore import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import kotlin.test.assertEquals class TestDataSourceImplTest { private lateinit var testDataStore: DataStore<Preferences> private lateinit var dataSource: TestDataSourceImpl @Before fun setup() { // 初始化内存测试DataStore testDataStore = TestPreferencesDataStore() dataSource = TestDataSourceImpl(testDataStore) } @Test fun `存储布尔值后能正确写入DataStore`() = runTest { // 执行存储操作 dataSource.setTestFlag(true) // 验证DataStore中的值 val storedValue = testDataStore.data.first()[TestDataSourceImpl.testFlag] assertEquals(true, storedValue) } @Test fun `读取操作能正确获取已存储的布尔值`() = runTest { // 预先写入测试值 testDataStore.edit { it[TestDataSourceImpl.testFlag] = false } // 获取并验证结果 val retrievedValue = dataSource.getTestFlag().first() assertEquals(false, retrievedValue) } @Test fun `无存储值时读取返回null`() = runTest { // 直接读取初始空状态的DataStore val retrievedValue = dataSource.getTestFlag().first() assertEquals(null, retrievedValue) } }
四、测试用例说明
- 存储验证:测试
setTestFlag是否能将布尔值正确持久化到DataStore中 - 读取验证:测试
getTestFlag是否能正确获取已存储的布尔值 - 默认值验证:测试当没有任何存储记录时,读取操作返回null的逻辑是否符合预期
内容的提问来源于stack exchange,提问作者Guruprasad
相关产品推荐
相关产品推荐

