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

Data Store单元测试报错:单次测试仅允许调用一次runTest

解决Data Store测试中Only a single call to runTest can be performed during one test报错

问题原因

kotlinx.coroutines.test的runTest在单个测试周期内仅允许调用一次,你的测试方法和@After清理方法各调用了一次,触发了这个限制。

解决方案

去掉@After方法中的runTest,直接利用已创建的TestScope执行清理操作——TestScope本身已绑定测试调度器,可直接运行挂起任务。

修改后的tearDown方法

@After
fun tearDown() {
    // 在测试作用域内启动协程执行Data Store清理
    testScope.launch {
        testDataStore.edit { it.clear() }
    }
    // 等待所有调度的协程任务执行完成
    testScope.runCurrent()
    // 取消测试作用域
    testScope.cancel()
}

完整修改后的测试代码

@HiltAndroidTest
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class MyPreferencesDataSourceTest {
    private val testContext: Context = ApplicationProvider.getApplicationContext()
    private val testDispatcher = UnconfinedTestDispatcher()
    private val testScope = TestScope(testDispatcher + Job())

    @get:Rule(order = 0)
    var hiltRule = HiltAndroidRule(this)

    @get:Rule(order = 1)
    val mainDispatcherRule = MainDispatcherRule()

    private val testDataStore: DataStore<Preferences> = PreferenceDataStoreFactory.create(
        scope = testScope,
        produceFile = {
            testContext.preferencesDataStoreFile(
                name = AppConstants.APP_NAME,
            )
        },
    )

    private lateinit var appPreferenceDataSource: AppPreferenceDataSource

    @Before
    fun setUp() {
        hiltRule.inject()
        appPreferenceDataSource = AppPreferenceDataSource(
            dataStore = testDataStore,
        )
    }

    @After
    fun tearDown() {
        testScope.launch {
            testDataStore.edit { it.clear() }
        }
        testScope.runCurrent()
        testScope.cancel()
    }

    @Test
    fun getCurrencyBase_returnsNull() = testScope.runTest {
        val result = appPreferenceDataSource.getData().first()

        Assert.assertNull(result)
    }
}

原理说明

TestScope.runCurrent()会立即执行所有已调度到测试调度器的协程任务,无需额外用runTest包装,既完成了Data Store的清理,又避免了多次调用runTest的冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:20:27