android / android/codelab-android-datastore
"multiple instances" error when removing value during unit testing
- Dominant language
- Kotlin
- Stars
- 240
- Forks
- 113
- PR merge metrics
- No merged PRs in 30d
Description
When trying to remove some key from datastore-preferences during unittest I'm getting an error about "multiple instances" of the datastore.
The following code reproduces the problem:
`
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStoreFile
import androidx.test.core.app.ApplicationProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.SupervisorJob
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
@ExperimentalCoroutinesApi
@RunWith(RobolectricTestRunner::class)
class TestDataStore {
companion object {
private val DATASTORE_KEY = stringPreferencesKey("DATASTORE_KEY")
}
@get:Rule
val testCoroutineRule = TestCoroutineRule()
private lateinit var dataStore: DataStore
@Before
fun setup() {
val context = ApplicationProvider.getApplicationContext()
dataStore =
PreferenceDataStoreFactory.create(
scope = CoroutineScope(testCoroutineRule.testCoroutineDispatcher + SupervisorJob())
) {
context.preferencesDataStoreFile("preferences")
}
}
@Test
fun test() {
testCoroutineRule.runBlockingTest {
dataStore.edit { it[DATASTORE_KEY] = "team" }
dataStore.edit { it.remove(DATASTORE_KEY) }
}
}
}
`
The stacktrace:
`Unable to rename C:\Users\Cassio\AppData\Local\Temp\robolectric-Method_test8095984772844777287\com.nautiluslog.data.test-dataDir\files\datastore\preferences.preferences_pb.tmp.This likely means that there are multiple instances of DataStore for this file. Ensure that you are only creating a single instance of datastore for this file.
java.io.IOException: Unable to rename C:\Users\Cassio\AppData\Local\Temp\robolectric-Method_test8095984772844777287\com.nautiluslog.data.test-dataDir\files\datastore\preferences.preferences_pb.tmp.This likely means that there are multiple instances of DataStore for this file. Ensure that you are only creating a single instance of datastore for this file.
at androidx.datastore.core.SingleProcessDataStore.writeData$datastore_core(SingleProcessDataStore.kt:433)
at androidx.datastore.core.SingleProcessDataStore.transformAndWrite(SingleProcessDataStore.kt:410)
at androidx.datastore.core.SingleProcessDataStore.handleUpdate(SingleProcessDataStore.kt:276)
at androidx.datastore.core.SingleProcessDataStore.access$handleUpdate(SingleProcessDataStore.kt:76)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invokeSuspend(SingleProcessDataStore.kt:242)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invoke(SingleProcessDataStore.kt)
at androidx.datastore.core.SingleProcessDataStore$actor$3.invoke(SingleProcessDataStore.kt)
at androidx.datastore.core.SimpleActor$offer$2.invokeSuspend(SimpleActor.kt:122)
(Coroutine boundary)
at com.nautiluslog.data.repository.TestDataStore$test$1.invokeSuspend(TestDataStore.kt:54)
at com.nautiluslog.testutils.TestCoroutineRule$runBlockingTest$1.invokeSuspend(TestCoroutineRule.kt:30)
at kotlinx.coroutines.test.TestBuildersKt$runBlockingTest$deferred$1.invokeSuspend(TestBuilders.kt:50)`
Contributor guide
Research direction
Start by running the reproducer in TestDataStore.kt, especially the setup and two dataStore.edit calls, using the TestCoroutineRule from TestCoroutineRule.kt. Read the SingleProcessDataStore.kt stack-trace locations to understand the failed write and rename; done means the test can remove DATASTORE_KEY without the multiple-instances or rename error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- database, mobile
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100