Ana*_*dze 27 android unit-testing mockito viewmodel kotlin
我正在尝试测试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)
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 Kotlin 并具有以下依赖项:
testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-inline:2.23.4"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0"
Run Code Online (Sandbox Code Playgroud)
这是我的进口:
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
Run Code Online (Sandbox Code Playgroud)
奇怪的是它以前可以工作,我不知道发生了什么可能会影响它。
Nab*_*bzi 30
让匹配器与 Kotlin 一起工作可能是一个问题。如果您有一个用 kotlin 编写的方法不接受可空参数,那么我们无法使用 Mockito.any() 匹配它。这是因为它可以返回 void 并且这不能分配给不可为空的参数。
如果匹配的方法是用 Java 编写的,那么我认为它会起作用,因为所有 Java 对象都是隐式可为空的。
一种可能的解决方案是使用像mockito-kotlin这样的库, 但是您可以自己用几行代码轻松解决这个问题。
如果你需要输入任何(类型:类)
private fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
Run Code Online (Sandbox Code Playgroud)
或者
您可以使用此匹配器代替 Matchers.any() :
object MockitoHelper {
fun <T> anyObject(): T {
Mockito.any<T>()
return uninitialized()
}
@Suppress("UNCHECKED_CAST")
fun <T> uninitialized(): T = null as T
}
Run Code Online (Sandbox Code Playgroud)
并在您的 kotlin 测试中使用MockitoHelper.anyObject()而不是any()。
您可以在这篇文章中找到更多信息:在 Kotlin 中使用 Mockito
在这篇文章中有一个关于可能的解决方案的讨论: Is it possible to use Mockito in Kotlin?
Hao*_*min 22
@Ana Koridze 在问题的评论部分提到了正确的解决方案。是的,如果您使用的是 Koltin + mockitoKotlin。确保您正在使用以下导入:
1 - 使用 Mockito-kotlin:
import org.mockito.kotlin.any 来自 Mockito-kotlin 而不是
import org.mockito.Mockito.any
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"
Run Code Online (Sandbox Code Playgroud)
2 - 或者如果您使用的是 nhaarman 在插入之前创建的旧版 mockito kotlin 版本
import com.nhaarman.mockitokotlin2.any 来自 nhaaram 的 Mockito-kotlin 而不是 import org.mockito.Mockito.any
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:$mockito_kotlin2_version"
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果您使用的是 Android Studio 或 IntelliJ IDEA。在any()从mockitokotlin库应该是italic默认样式/颜色方案。
注意any()行尾。这是来自mockitokotlin
这是any()来自mockito
感谢@Sattar 推荐的编辑。
小智 13
mockito-kotlin添加了对可空参数的支持anyOrNull()
`when`(myMock.doesThis(any(), anyOrNull())).thenReturn(someObject)
Run Code Online (Sandbox Code Playgroud)
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"
Run Code Online (Sandbox Code Playgroud)
这将使用任何适用于 kotlin 的库,因为这是 Mockito 的包装库,但适用于 kotlin