How to test Proto datastore? The Medium article by Simona Stojanovic doesn't work for proto datastore
@simona-anomis 已经在做这个了。
开始于 2022年12月12日。
评估
这个 Issue 还没有评估数据。
描述
I tried the approach in Simona Stojanovic @simona-anomis Medium article but it doesn't work for proto datastore. The issue is that testCoroutineScope.runBlockingTest gives me an error.
The entire code is the same as in the Medium article except for the part where the datastore is created:
DataStoreFactory.create(
serializer = UserPreferencesSerializer,
produceFile = { testContext.dataStoreFile(DATA_STORE_FILE_NAME) },
scope = testCoroutineScope
)
This is the full test file I run as an Instrumented Test:
package com.xkcd.comiclist_data.repository
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.dataStoreFile
import androidx.test.platform.app.InstrumentationRegistry
import app.cash.turbine.test
import com.xkcd.core.XkcdSettings
import com.xkcd.core.settings.XkcdSettingsSerializer
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.test.*
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@HiltAndroidTest
class XkcdSettingsRepositoryImplTest {
@get:Rule
var hiltRule = HiltAndroidRule(this)
private val testContext: Context =
InstrumentationRegistry.getInstrumentation().targetContext
private val testCoroutineDispatcher: TestCoroutineDispatcher =
TestCoroutineDispatcher()
@OptIn(ExperimentalCoroutinesApi::class)
private val testCoroutineScope =
TestCoroutineScope(testCoroutineDispatcher + Job())
private val testDataStore: DataStore<XkcdSettings> = DataStoreFactory.create(
serializer = XkcdSettingsSerializer,
produceFile = { testContext.dataStoreFile(XkcdSettingsSerializer.testDataStoreName) },
scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
)
private val repository: XkcdSettingsRepositoryImpl = XkcdSettingsRepositoryImpl(testDataStore)
@OptIn(ExperimentalCoroutinesApi::class)
@Before
fun setup() {
Dispatchers.setMain(testCoroutineDispatcher)
}
@OptIn(ExperimentalCoroutinesApi::class)
@After
fun cleanUp() {
Dispatchers.resetMain()
testCoroutineDispatcher.cleanupTestCoroutines()
testCoroutineScope.cancel()
}
@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun dummyTest() {
testCoroutineScope.runBlockingTest {
repository.getXkcdSettings().test {
println(awaitItem())
awaitComplete()
}
}
}
}
The error I get states that This job has not completed yet:
java.lang.IllegalStateException: This job has not completed yet
at kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1190)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersDeprecatedKt.runBlockingTest(TestBuildersDeprecated.kt:67)
at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(Unknown Source:1)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersDeprecatedKt.runBlockingTest(TestBuildersDeprecated.kt:126)
at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(Unknown Source:1)
at com.xkcd.comiclist_data.repository.XkcdSettingsRepositoryImplTest.dummyTest(XkcdSettingsRepositoryImplTest.kt:60)
Here is the full XkcdSettingsRepositoryImpl:
package com.xkcd.comiclist_data.repository
import androidx.datastore.core.DataStore
import com.xkcd.comiclist_domain.model.Comic
import com.xkcd.comiclist_domain.model.CurrentXkcdSettings
import com.xkcd.comiclist_domain.repository.XkcdSettingsRepository
import com.xkcd.core.XkcdSettings
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.flow
import javax.inject.Inject
import kotlin.math.max
class XkcdSettingsRepositoryImpl @Inject constructor(
private val xkcdSettings: DataStore<XkcdSettings>
): XkcdSettingsRepository {
override suspend fun updateUserName(userName: String) {
xkcdSettings.updateData { settings ->
settings.toBuilder().setUserName(userName).build()
}
}
override suspend fun updateLatestComic(comic: Comic) {
xkcdSettings.updateData { settings ->
settings.toBuilder().setLatestComicNum(max(comic.num, settings.latestComicNum.toInt()).toLong()).build()
}
}
override suspend fun updateSelectedTab(selectedTab: XkcdSettings.SelectedTab) {
xkcdSettings.updateData { settings ->
settings.toBuilder().setSelectedComicTab(selectedTab).build()
}
}
override suspend fun updateSelectedComicSort(selectedComicSort: XkcdSettings.SelectedComicSort) {
xkcdSettings.updateData { settings ->
settings.toBuilder().setSelectedComicSort(selectedComicSort).build()
}
}
override suspend fun getXkcdSettings(): Flow<CurrentXkcdSettings> = flow {
xkcdSettings.data.collectLatest {
emit(CurrentXkcdSettings(
userName = it.userName,
latestComicNum = it.latestComicNum.toInt(),
selectedTab = it.selectedComicTab,
selectedComicSort = it.selectedComicSort
))
}
}
}
- 主要语言
- Kotlin
- 星标
- 242
- 派生
- 115
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
android/codelab-android-datastore 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 62/100
-
难度 4/5 3-5 天 新手友好度 25/100
android/codelab-android-datastore#83 · 2 条评论 · 2 个 reaction ·
-
难度 3/5 1-2 天 新手友好度 45/100
-
难度 1/5 1 小时以内 新手友好度 55/100
-
难度 3/5 1-2 天 新手友好度 35/100
查看 android/codelab-android-datastore 的全部 Issue
相似的 Issue
-
afk-ok area:frontend size:S
难度 2/5 1-3 小时 新手友好度 87/100
enorm-labs/event-junkie#4154 ·
维护者通常 1 天内回复
-
enhancement
难度 2/5 1-3 小时 新手友好度 68/100
PixelPlayerHQ/PixelPlayerOSS#193 ·
维护者通常 1 天内回复
-
bug web-server
难度 2/5 1-3 小时 新手友好度 78/100
jooby-project/jooby#4035 ·
维护者通常 1 天内回复
-
Android: theme prop is ignored in R8-minified release builds (Theme enum is not Enumerable)可能已有人在做 @1kuko3 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 74/100
-
Bug
难度 2/5 1-3 小时 新手友好度 61/100
keiyoushi/extensions-source#20494 · 1 个 reaction ·
维护者通常 1 天内回复