我正在尝试测试ViewModel,以确保Livedata被正确更新。然而当使用ArgumentMatchers.any()时,它以IllegalStateException失败,并说
ArgumentMatchers.any(mViewModel.CountSubscriber::class.java)不能为空。
@Test
fun emitValueIfCountIs7() {
doAnswer { invocation: InvocationOnMock ->
val subscriber: mViewModel.CountSubscriber = invocation.getArgument(0)
subscriber.onNext(7)
null
}.`when`(countUseCase).execute(ArgumentMatchers.any(mViewModel.CountSubscriber::class.java),
ArgumentMatchers.any(Parameters::class.java))
// When
mViewModel.getCount()
// Verify
assert(mViewModel.countResponse.value != null)
}
我使用的是Kotlin,并有以下依赖关系。
testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-inline:2.23.4"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0"
这是我的导入。
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.nhaarman.mockitokotlin2.doAnswer
import io.reactivex.Observable
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.ArgumentMatchers.any
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.invocation.InvocationOnMock
奇怪的是,以前是可以正常工作的 我不知道发生了什么事,会影响到这一点。
让匹配器与Kotlin一起工作是个问题。如果你有一个用kotlin写的方法,它不接受一个可空参数,那么我们就不能用Mockito.any()来匹配它。这是因为它可以返回void,而这是不能分配给一个非可空参数的。
如果被匹配的方法是用Java写的,那么我认为它可以工作,因为所有的Java对象都是隐式可空的。
一个可能的解决方案是使用类似于 mockito-kotlin 但你可以自己用几行代码轻松解决这个问题。
如果你需要typed any(type: Class)
private fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
或
你可以用这个匹配器代替Matchers.any()。
object MockitoHelper {
fun <T> anyObject(): T {
Mockito.any<T>()
return uninitialized()
}
@Suppress("UNCHECKED_CAST")
fun <T> uninitialized(): T = null as T
}
并使用 MockitoHelper.anyObject()
而不是 any()
的测试中。
你可以在这篇文章中找到更多信息。在Kotlin中使用Mockito
在这个帖子里有一个关于可能的解决方案的讨论。是否可以在Kotlin中使用Mockito?