提问人:Satyam Gondhale 提问时间:9/29/2023 更新时间:10/3/2023 访问量:110
错误:无法调用“String.isEmpty()”,因为 mockk kotlin 数据存储函数的“parent.path”为 null
Error Cannot invoke "String.isEmpty()" because "parent.path" is null for mockk kotlin datastore functions
问:
我正在使用 koltin 框架编写一个用于数据存储的 Test 类。类如下所示mockk
`open class MyStorageClass(context: Context) : Storage {
private val testDataStore = context.dataStore
private val dataException: suspend FlowCollector<Preferences>.(cause: Throwable) -> Unit = { exception ->
when (exception) {
is IOException -> emit(emptyPreferences())
else -> throw exception
}
}
override suspend fun <T> getPreferenceFlow(key: Preferences.Key<T>, defaultValue: T): Flow<T> =
testDataStore.data
.catch(dataException)
.map { preferences ->
preferences[key] ?: defaultValue
.also { Timber.d("Got preference : ${key.name} : $it") }
}
}`
存储接口的样子
`interface Storage {
suspend fun <T> getPreferenceFlow(key: Preferences.Key<T>, defaultValue: T): Flow<T>
}`
kotlin 中使用的测试类写成mockk
`class HnavStorageTest {
private lateinit var dataStore: DataStore<Preferences>
lateinit var preferences: Preferences
lateinit var mockContext: Context
lateinit var sut: HnavStorage
@Before
fun setup() {
MockKAnnotations.init(this, true)
dataStore = mockk(relaxed = true)
preferences = mockk(relaxed = true)
mockContext = mockk(relaxed = true)
sut = HnavStorage(mockContext)
}
@Test
fun `test getPreference Flow`() = runBlocking {
coEvery { dataStore.data } returns flowOf(preferences)
val key: Preferences.Key<String> = stringPreferencesKey(name = "test_key")
val defaultValue = "test_value"
val expectedValue = "mocked_value"
every { preferences[key] } returns expectedValue
val flow = sut.getPreferenceFlow(key, defaultValue)
var result: String? = null
flow.collect {
result = it
}
assert(result == expectedValue)
verify { Timber.d("Get preference value: ${key.name} : $expectedValue") }
}
}`
运行 Test 类后,我收到错误
`Cannot invoke "String.isEmpty()" because "parent.path" is null
java.lang.NullPointerException: Cannot invoke "String.isEmpty()" because "parent.path" is null
at java.base/java.io.File.<init>(File.java:364)
at androidx.datastore.DataStoreFile.dataStoreFile(DataStoreFile.kt:36)
at androidx.datastore.preferences.PreferenceDataStoreFile.preferencesDataStoreFile(PreferenceDataStoreFile.kt:38)
at androidx.datastore.preferences.PreferenceDataStoreSingletonDelegate$getValue$1$1.invoke(PreferenceDataStoreDelegate.kt:107)
at androidx.datastore.preferences.PreferenceDataStoreSingletonDelegate$getValue$1$1.invoke(PreferenceDataStoreDelegate.kt:106)
at androidx.datastore.preferences.core.PreferenceDataStoreFactory$create$delegate$1.invoke(PreferenceDataStoreFactory.kt:69)`
如何解决这个问题?任何帮助将不胜感激
我尝试模拟首选项,检查异常但找不到它
答:
0赞
ObscureCookie
10/3/2023
#1
您需要定义将返回的内容。如果是扩展属性,则用于使其可模拟。mockContext.dataStore
every
mockContext.dataStore
mockkStatic(Context::dataStore)
@Before
fun setup() {
MockKAnnotations.init(this, true)
dataStore = mockk(relaxed = true)
preferences = mockk(relaxed = true)
mockContext = mockk(relaxed = true)
mockkStatic(Context::dataStore)
every { mockContext.dataStore } returns dataStore
sut = HnavStorage(mockContext)
}
@After
fun tearDown() {
unmockkAll()
}
评论