Hi all :android-wave: , I am trying to add tests f...
# android
a
Hi all 👋 , I am trying to add tests for data store by following this article - https://medium.com/androiddevelopers/datastore-and-testing-edf7ae8df3d8. I am getting the following error
Copy code
kotlinx.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 color
solved 1
Test code
Copy code
@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
    }
}
MyPreferencesDataSource
Copy code
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
        }
    }
}
• Tried with and without
MainDispatcherRule
. • Tried with
UnconfinedTestDispatcher
and also with
StandardTestDispatcher
.
Going through the older messages here, Let me add more context, 1. I am not using mockk (So, not this issue - https://kotlinlang.slack.com/archives/C1CFAFJSK/p1688240798449439) 2. I have tried with timeout as 2 seconds as well. (https://github.com/Kotlin/kotlinx.coroutines/issues/3270)
Update: I was able to fix the test. 😃 . I had to use
testScope.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-beta02
s
@Abhimanyu check my repo, I have implemented the
data-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