gpt4 book ai didi

kotlin - ArgumentCaptor 与 InOrder 使用不同参数验证后续回调

转载 作者:行者123 更新时间:2023-12-01 19:38:59 24 4
gpt4 key购买 nike

我正在测试使用 Architecture Components 中的 Room 库生成的 DAO 类。我想检查连接多个表的查询返回的 LiveData 是否会在数据更改时更新。

我一开始使用 InOrder 验证,但发现无论我想断言什么参数,Mockito 都会说该方法是用另一个方法调用的(当我将断言更改为该方法时) ,它会说这是另一个)。

事实证明,使用 ArgumentCaptor 可以很好地实现此目的,这也是本问题的主题:

为什么 ArgumentCaptor 验证在这里起作用,但 InOrder 不起作用?

查看 how to verify multiple method calls with different params 问题的答案,这两种方法都应该可以正常工作。

这是我的测试的简化版本,展示了该问题:

package com.example

import com.nhaarman.mockito_kotlin.argumentCaptor
import com.nhaarman.mockito_kotlin.check
import com.nhaarman.mockito_kotlin.mock
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.*
import org.mockito.junit.MockitoJUnitRunner

@Suppress("IllegalIdentifier")
@RunWith(MockitoJUnitRunner::class)
class MultipleCallbacksVanillaTest {

private val java = Language("Java")
private val javascript = Language("JavaScript")
private val kotlin = Language("Kotlin")

private val firstList = emptyList<Language>()
private val secondList = listOf(java)
private val thirdList = listOf(java, javascript, kotlin)
private val lastList = listOf(java, kotlin)

@Test fun `using argument captor`() {
// given
val observer = mock<Observer<List<Language>>>()
val liveData = MutableLiveData<List<Language>>()

// when
liveData.observeForever(observer)
liveData.value = firstList
liveData.value = secondList
liveData.value = thirdList
liveData.value = lastList

// then
argumentCaptor<List<Language>>().run {
verify(observer, times(4)).onChanged(capture())
val (firstValue, secondValue, thirdValue, lastValue) = allValues
assertEquals(firstList, firstValue)
assertEquals(secondList, secondValue)
assertEquals(thirdList, thirdValue)
assertEquals(lastList, lastValue)
}
}

@Test fun `using in order`() {
// given
val observer = mock<Observer<List<Language>>>()
val liveData = MutableLiveData<List<Language>>()

// when
liveData.observeForever(observer)
liveData.value = firstList
liveData.value = secondList
liveData.value = thirdList
liveData.value = lastList

// then
inOrder(observer).run {
verify(observer).onChanged(check { assertEquals(firstList, it) })
verify(observer).onChanged(check { assertEquals(secondList, it) })
verify(observer).onChanged(check { assertEquals(thirdList, it) })
verify(observer).onChanged(check { assertEquals(lastList, it) })
}
verifyNoMoreInteractions(observer)
}

}

data class Language(val name: String)

interface Observer<in T> {
fun onChanged(value: T?)
}

class MutableLiveData<T : Any> {
var value: T
get() = _value
set(value) {
observers.forEach { it.onChanged(value) }
_value = value
}

private lateinit var _value: T

private var observers = mutableSetOf<Observer<T>>()

fun observeForever(observer: Observer<T>) {
if (::_value.isInitialized) observer.onChanged(_value)
observers.add(observer)
}
}

using argument captor 通过,但 using in order 失败并显示一条消息:

java.lang.AssertionError:
Expected :[]
Actual :[Language(name=Java)]

最佳答案

TL;DR - 这似乎是 Mockito-Kotlin's 上的错误和/或错误文档。部分,就其 check 功能而言。

Mockito-Kotlin 的 wiki says :

If you want to do more assertions on the received argument, you can use check. [...] If you want your test to fail inside a check invocation, you should make sure the body throws an error [...]

check的实现 calls Mockito's argThat ,并将提供的谓词作为参数传递。然而,the documentation for ArgumentMatcher states :

The method should never assert if the argument doesn't match. It should only return false.

因此 Mockito-Kotlin 的文档与此约束直接矛盾。

我不知道如何解决这个问题,但你现在可以完全避免 check ,并直接使用 argThat (返回 false > 酌情使用,而不是抛出)。

关于kotlin - ArgumentCaptor 与 InOrder 使用不同参数验证后续回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48249816/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com