简体   繁体   English

如何使用 mockk 模拟“删除”共享偏好的扩展?

[英]How to mock "remove" extension of shared preferences using mockk?

Problem Description问题描述

I have a method of a data source class that makes the following call to a Shared Preferences extension:我有一个数据源 class 的方法,它对共享首选项扩展进行以下调用:

override suspend fun removePendingBatch() {
    preferences.remove(pendingBatchKey)
}

preferences is an instance of Shared Preferences首选项共享首选项的一个实例

I need to do an unit test using mockk that checks if when calling this method of my data source class the call to this shared preferences extension is made.我需要使用mockk进行单元测试,检查在调用我的数据源 class 的此方法时是否调用了此共享首选项扩展。

In my test scenario I instantiate my preferences object like this:在我的测试场景中,我像这样实例化我的偏好 object:

private val preferences: SharedPreferences = mockk()

This is my unit test:这是我的单元测试:

@Test
fun `when removePendingBatch() is called then remove from preferences`() = runBlockingTest {
    every { preferences.remove(PENDING_BATCH_KEY) } just runs
    batchDataSource.removePendingBatch()
    verify(exactly = 1) { preferences.remove(PENDING_BATCH_KEY) }
}

The problem happens when I try to run this unit test, a mockk error saying there is no mock response is thrown:当我尝试运行此单元测试时,会出现问题,抛出一个提示没有模拟响应的模拟错误:

no answer found for: Editor(child of #1#3).commit()
io.mockk.MockKException: no answer found for: Editor(child of #1#3).commit()
    at io.mockk.impl.stub.MockKStub.defaultAnswer(MockKStub.kt:90)
    at io.mockk.impl.stub.MockKStub.answer(MockKStub.kt:42)
    at io.mockk.impl.recording.states.AnsweringState.call(AnsweringState.kt:16)
    at io.mockk.impl.recording.CommonCallRecorder.call(CommonCallRecorder.kt:53)
    at io.mockk.impl.stub.MockKStub.handleInvocation(MockKStub.kt:263)
...

My attempt fails我的尝试失败了

I imagine that I should mock the editor method call inside the shared preferences, however it seems to me that the mockk can't do that very well with the just runs statement, because when trying to do it the following syntax error appears:我想我应该在共享首选项中模拟编辑器方法调用,但是在我看来,模拟不能用just runs语句做得很好,因为在尝试这样做时会出现以下语法错误:

在此处输入图像描述

I managed to solve this problem by mocking the commit method coming from the SharedPreferences.Editor object by this way:我设法通过来自SharedPreferences.Editor object 的commit方法 mocking 解决了这个问题:

every { preferences.edit().commit() } returns RandomUtils.nextBoolean()

In this case, just return any boolean, so we can mock the "remove" method, my complete test looks like this:在这种情况下,只需返回任何 boolean,这样我们就可以模拟“删除”方法,我的完整测试如下所示:

@Test
fun `when removePendingBatch() is called then remove from preferences`() = runBlockingTest {
    every { preferences.edit().commit() } returns RandomUtils.nextBoolean()
    every { preferences.remove(PENDING_BATCH_KEY) } just runs
    batchDataSource.removePendingBatch()
    verify(exactly = 1) { preferences.remove(PENDING_BATCH_KEY) }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM