错误无法调用“String.isEmpty()”,因为“parent.path”对于mockk kotlin数据存储函数为空

问题描述 投票:0回答:1

我正在使用 koltin 的

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") }
    }
}` 

运行测试类后,我收到错误如下

`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)` 

如何解决这个问题?任何帮助将不胜感激

我尝试模拟首选项,检查异常但找不到它

android string sharedpreferences datastore mockk
1个回答
0
投票

您需要定义

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()
}
© www.soinside.com 2019 - 2024. All rights reserved.