Abhimanyu
07/27/2024, 9:24 AMkotlinx.coroutines.test.UncompletedCoroutinesError: After waiting for 5s, the test coroutine is not completing, there were active child jobs: [StandaloneCoroutine{Active}@1ecec6f]
More details in thread 🧵 .
Please help thank you colorAbhimanyu
07/27/2024, 9:25 AM@HiltAndroidTest
@RunWith(AndroidJUnit4::class)
internal class MyPreferencesDataSourceTest {
@get:Rule(order = 0)
var hiltRule: HiltAndroidRule = HiltAndroidRule(this)
@get:Rule(order = 1)
val mainDispatcherRule: MainDispatcherRule = MainDispatcherRule()
private val testContext: Context = ApplicationProvider.getApplicationContext()
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(
context = testDispatcher + Job(),
)
private lateinit var testDataStore: DataStore<Preferences>
private lateinit var myPreferencesDataSource: MyPreferencesDataSource
@Before
fun setUp() {
hiltRule.inject()
testDataStore = PreferenceDataStoreFactory.create(
scope = testScope,
produceFile = {
testContext.preferencesDataStoreFile(
name = AppConstants.APP_NAME,
)
},
)
myPreferencesDataSource = MyPreferencesDataSource(
dataStore = testDataStore,
myLogger = FakeMyLoggerImpl(),
)
}
@After
fun tearDown() {
testScope.cancel()
}
@Test
fun getDataTimestampLastBackup_returnsZero() = runTestAndClearDataStore {
val result = myPreferencesDataSource.getDataTimestamp().first()?.lastBackup
Assert.assertEquals(
0L,
result,
)
}
private fun runTestAndClearDataStore(
block: suspend () -> Unit,
) = testScope.runTest(
timeout = 5.seconds,
) {
block()
testDataStore.edit {
it.clear()
}
}
companion object {
const val TEST_ID: Int = 34
const val TEST_TIMESTAMP: Long = 32654L
}
}
Abhimanyu
07/27/2024, 9:26 AMMyPreferencesDataSource
public class MyPreferencesDataSource(
private val dataStore: DataStore<Preferences>,
private val myLogger: MyLogger,
) {
private val preferences: Flow<Preferences> = dataStore.data
.catch { exception ->
myLogger.logInfo(
message = "Error reading preferences. ${exception.localizedMessage}",
)
emit(
value = emptyPreferences(),
)
}
public fun getDataTimestamp(): Flow<DataTimestamp?> {
return preferences.map {
DataTimestamp(
lastBackup = it[DataStoreConstants.DataTimestamp.LAST_DATA_BACKUP].orZero(),
lastChange = it[DataStoreConstants.DataTimestamp.LAST_DATA_CHANGE].orZero(),
)
}
}
private suspend fun tryDataStoreEdit(
block: suspend () -> Unit,
): Boolean {
return try {
block()
true
} catch (
ioException: IOException,
) {
false
}
}
}
Abhimanyu
07/27/2024, 9:27 AMMainDispatcherRule
.
• Tried with UnconfinedTestDispatcher
and also with StandardTestDispatcher
.Abhimanyu
07/27/2024, 9:50 AMAbhimanyu
07/27/2024, 10:02 AMtestScope.backgroundScope
instead of testScope
in PreferenceDataStoreFactory.create()
.
References,
• https://stackoverflow.com/a/78433617/9636037
• https://developer.android.com/jetpack/androidx/releases/datastore#1.1.0-beta02Saadat Sayem
10/10/2024, 8:59 AMdata-store
unit testing in my project. Let me know if you have any question. And please don't forget to give a start to it. Thanks