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

如何为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 10:05:14