ArgumentMatchers.any不能为空

nkcskrwz  于 2022-11-08  发布在  其他
关注(0)|答案(7)|浏览(150)

我尝试测试ViewModel以确保livedata得到正确更新。但是,当使用ArgumentMatchers.any()时,它失败了,IllegalStateException说:
任何(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

奇怪的是,它以前曾经工作过,而我不知道发生了什么事,可能会影响到这一点。

bwleehnv

bwleehnv1#

让匹配器与Kotlin一起工作可能是个问题。如果你有一个用kotlin编写的方法,它不接受一个可空参数,那么我们就不能用Mockito.any()来匹配它。这是因为它会返回void,而这是不能赋给一个不可空参数的。
如果匹配的方法是用Java编写的,那么我认为它将工作,因为所有Java对象都是隐式可空的。
一个可能的解决方案是使用mockito-kotlin这样的库,但是您可以自己用几行代码轻松地解决这个问题。
如果需要键入任何(键入:类)

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
}

并在Kotlin测试中使用MockitoHelper.anyObject()而不是any()
您可以在此帖子中找到更多信息:Using Mockito with Kotlin
在这篇文章中有一个关于可能的解决方案的讨论:Is it possible to use Mockito in Kotlin?

3vpjnl9f

3vpjnl9f2#

正确的解决方案在问题的注解部分由@Ana Koridze提到。是的,如果您使用的是Koltin + mockitoKotlin。请确保您使用的是以下导入:

1 -使用Mockito-kotlin:

来自Mockito-kotlin的import org.mockito.kotlin.any,而不是import org.mockito.Mockito.any

testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"

2 -或者,如果您使用的是nhaarman在集成之前创建的旧mockitoKotlin原始版本

来自nhaaram的Mockito-kotlin的import com.nhaarman.mockitokotlin2.any,而不是import org.mockito.Mockito.any

testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:$mockito_kotlin2_version"

顺便说一句,如果你使用的是Android Studio或IntelliJ IDEA,mockitokotlin库中的any()默认样式/配色方案应该是 * italic *。
请注意行尾的any()。它来自mockitokotlin

这是来自mockito的any()

感谢@Sattar的推荐编辑。

vmdwslir

vmdwslir3#

mockito-kotlin添加了对anyOrNull()的可空参数的支持

`when`(myMock.doesThis(any(), anyOrNull())).thenReturn(someObject)
cnwbcb6i

cnwbcb6i4#

使用Mockito-kotlin

testImplementation "org.mockito.kotlin:mockito-kotlin:$mockito_kotlin_version"

这将使用任何适用于Kotlin的库,因为这是Mockito的 Package 库,但适用于kotlin

dojqjjoe

dojqjjoe5#

"这对我很有效"
1.或者用一个特定的anyTYPE()替换了所有通用的any(),即核心库org.mockito:mockito-core中的anyInt()anyList()等,它修复了(可空性)问题,似乎特定的类型定义可以处理空值。此选项不需要您导入任何额外的库

1.如果你真的需要使用泛型类型any(),添加这个正式的Mckito扩展库https://github.com/mockito/mockito-kotlin,并确保你使用这个库中的any()(通过确保你的导入中有这个import org.mockito.kotlin.any
我建议开始使用MockK库https://github.com/mockk/mockk,而不是Mockito,因为它是KMock库(otlin = MockK)
然而,如果您现在懒得切换或者可能处理遗留测试(就像我的例子:),这也应该可以解决您的问题。

2ic8powd

2ic8powd6#

对我来说,以上所有的解决方案都不够-除此之外,我还必须将被调用的方法标记为“open”方法。https://github.com/mockito/mockito-kotlin/wiki/Parameter-specified-as-non-null-is-null这个方法是final的,Mockito不能模拟它,所以我必须添加'open'。

mpbci0fu

mpbci0fu7#

我围绕Mockito的any()编写了一个简单的 Package 函数,并去掉了警告。

private fun <T> any() : T {
    return org.mockito.ArgumentMatchers.any()
}

我在Kotlin还是很绿色的,所以我不确定是否会有一些不想要的副作用。我把这个答案放在那里,以防它对任何人或某人给我反馈有帮助。

相关问题