Android 使用mockK测试 View 模型

标签 android kotlin mockk

我正在尝试使用mockK 库测试我的 View 模型。但我不知道该怎么做。这是我的课。我有一个用例和一个存储库:

    @ExperimentalCoroutinesApi
class MainViewModelTest {

    private val getRecentPhotosUseCase:GetRecentPhotosUseCase= mockk()
    private val recentPhotosRepository:RemoteRecentPhotosRepository= mockk()
    private val mainViewModel by lazy { RecentPhotosViewModel(getRecentPhotosUseCase) }
    @ExperimentalCoroutinesApi
    @get:Rule
    var mainCoroutineRule = MainCoroutineRule()

    @get:Rule
    var instantTaskExecutorRule = InstantTaskExecutorRule()

    @Before
    fun setupBefore(){
        startKoin {
            androidContext(App.getInstance())
            if (BuildConfig.DEBUG) androidLogger(Level.DEBUG)
            modules(appModules + domainModules + dataModules)
        }
    }

    @Test
    fun `get recent photo success`(){
         val map: MutableMap<String, String> = HashMap()
    map["format"] = "json"
    map["method"] = "flickr.photos.getRecent1"
    map["nojsoncallback"]="1"
    map["per_page"]="20"
    map["page"]= "1"
    val recentPhotoResponse = mockk<RecentPhotos>()
    //1- Mock calls
    every { runBlocking {recentPhotosRepository.getRecentPhotos(map)} } returns Success(recentPhotoResponse)
    mainViewModel.viewState.observeForever {  }
    runBlocking {mainViewModel.getRecentPhotos(map)}
    val getRecentPhotoSuccess= mainViewModel.viewState.value
    MatcherAssert.assertThat(
        "Received result [$getRecentPhotoSuccess] & mocked ${OnSuccess(recentPhotoResponse)} must be matches on each other!",
        getRecentPhotoSuccess,
        CoreMatchers.`is`(OnSuccess(recentPhotoResponse))
    )
    }
}

但是当我运行测试时,它给了我这个错误:

io.mockk.MockKException: no answer found for: GetRecentPhotosUseCase(#1).invoke({per_page=20, method=flickr.photos.getRecent1, format=json, page=1, nojsoncallback=1}, continuation {})

最佳答案

您需要告诉mockk getRecentPhotosUseCase.function(...) 的返回值是什么。您可以这样做:每个 {mock.call(...) } 返回 Value。您可以将 any() 作为参数,也可以使用具体值:

every { getRecentPhotosUseCase.function(any(), any(), ...) } returns YourResultValue
// or
every { getRecentPhotosUseCase.function(per_page = 20, ...) } returns YourResultValue

或者,如果您不想模拟 GetRecentPhotosUseCase 的结果(可能是因为它与您的测试场景无关),您可以使用 relaxed mock :

A relaxed mock is the mock that returns some simple value for all functions. This allows to skip specifying behavior for each case, while still allowing to stub things you need. For reference types, chained mocks are returned.

val getRecentPhotosUseCase:GetRecentPhotosUseCase= mockk(relaxed = true)

关于Android 使用mockK测试 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65655345/

相关文章:

android - MockK - 左匹配器的匹配模拟签名失败 : [any(), any()]

android - 如何为 MenuItem 设置标签?

android - 在具有Oreo及更高版本操作系统的Android设备中,如何从uri获取文件路径

Kotlin 和 MockK 抛出 com.sun.tools.attach.AttachNotSupportedException : no providers installed

Fragment 中的 Android Kotlin RecyclerView 无法正常工作

android - 如何格式化 kotlinx-datetime LocalDateTime?

kotlin - 如何捕获传递给模拟函数的参数并返回它?

android - InputConnection.commitText(CharSequence text, int newCursorPosition) 只能提交英文字符和数字?

android - 使用 onCreateContextMenu 从 listView 复制文本

android - 单击按钮时更改按钮的 drawableLeft