DataStoreを使った処理のユニットテストを書く際に、mockkでインスタンスを作って、入出力を書いて・・・・・・ってやってたんですが
NowInAndroidで以下のクラスを見つけました
そうだ、DataStoreってinterfaceなんだから、普通にInMemory版のDataStore実装すればいいだけですやん!
しかもめっちゃシンプルに実装できるやん!
class InMemoryDataStore<T>(initialValue: T) : DataStore<T> {
override val data = MutableStateFlow(initialValue)
override suspend fun updateData(
transform: suspend (t: T) -> T
): T = data.updateAndGet { transform(it) }
}
DataStoreのdataはFlowですが、上記ではMutableStateFlowになっています。
InMemoryDataStoreとしてであれば data.value
で現在の値にもアクセスできるわけですね。
これは便利!
PreferencesDataStoreを使っている場合、以下のように初期値をpreferenceの内容で指定できるようにしたり、直接値を確認できるようにしておけばさらに便利かもしれません。
open class InMemoryDataStore<T>(initialVale: T) : DataStore<T> {
private val valueFlow = MutableStateFlow(initialVale)
val value: T
get() = valueFlow.value
override val data: Flow<T> = valueFlow
override suspend fun updateData(transform: suspend (t: T) -> T): T =
valueFlow.updateAndGet { transform(it) }
}
class InMemoryPreferencesDataStore(
vararg initialValues: Preferences.Pair<*>,
) : InMemoryDataStore<Preferences>(preferencesOf(*initialValues)) {
operator fun <T> get(key: Preferences.Key<T>): T? = value[key]
}
このインスタンスをテスト対象クラスに渡して、結果を確認することでお手軽にユニットテストを書くことができますね
val dataStore = InMemoryPreferencesDataStore()
...
asertThat(dataStore.data.value.get(KEY)).isEqualTo(VALUE)