Java 可以在科特林使用Mockito吗?

Java 可以在科特林使用Mockito吗?,java,mocking,mockito,kotlin,Java,Mocking,Mockito,Kotlin,我面临的问题是Matchers.anyObject()返回null。当用于模拟只接受不可为null的类型的方法时,会引发“不应为null”异常 `when`(mockedBackend.login(anyObject())).thenAnswer { invocationOnMock -> someResponse } 模拟方法: public open fun login(userCredentials: UserCredentials): Response 有两种可能的解决办法:

我面临的问题是
Matchers.anyObject()
返回
null
。当用于模拟只接受不可为null的类型的方法时,会引发“不应为null”异常

`when`(mockedBackend.login(anyObject())).thenAnswer { invocationOnMock -> someResponse }
模拟方法:

public open fun login(userCredentials: UserCredentials): Response

有两种可能的解决办法:

private fun <T> anyObject(): T {
    Mockito.anyObject<T>()
    return uninitialized()
}

private fun <T> uninitialized(): T = null as T

@Test
fun myTest() {
    `when`(mockedBackend).login(anyObject())).thenAnswer { ... }
}
private fun anyObject():T{
Mockito.anyObject()
返回未初始化()
}
private fun uninitialized():T=null作为T
@试验
乐趣我的测试(){
`当`(mockedbend).login(anyObject())。然后回答{…}
}
另一个解决方法是

private fun <T> anyObject(): T {
    return Mockito.anyObject<T>()
}

@Test
fun myTest() {
    `when`(mockedBackend).login(anyObject())).thenAnswer { ... }
}
private fun anyObject():T{
返回Mockito.anyObject()
}
@试验
乐趣我的测试(){
`当`(mockedbend).login(anyObject())。然后回答{…}
}

这里是关于这个主题的,这里是第一个建议解决方法的地方。

我经常使用
verify
来确保传递给函数的参数也是正确的

要做到这一点,并且仍然避免NPE,您可以使用kotlin的elvis操作符。 例如:
verify(mock).func(相同(我的对象)?:我的对象)

这样,mockito就满足了,因为它实际上验证了变量,kotlin满足了,因为我们传递了一个非null对象

我偶然发现的另一件事是mockito kotlin库,它正好解决了这个问题

您可以使用以下帮助函数在Kotlin中使用Mockito的any()、eq()和capture()匹配器:

/**
 * Returns Mockito.eq() as nullable type to avoid java.lang.IllegalStateException when
 * null is returned.
 *
 * Generic T is nullable because implicitly bounded by Any?.
 */
fun <T> eq(obj: T): T = Mockito.eq<T>(obj)

/**
 * Returns Mockito.any() as nullable type to avoid java.lang.IllegalStateException when
 * null is returned.
 */
fun <T> any(): T = Mockito.any<T>()

/**
 * Returns ArgumentCaptor.capture() as nullable type to avoid java.lang.IllegalStateException
 * when null is returned.
 */
fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
/**
*返回Mockito.eq()作为可空类型,以避免在
*返回null。
*
*泛型T可为null,因为它隐式地由Any?限定?。
*/
趣味情商(obj:T):T=Mockito.eq(obj)
/**
*返回Mockito.any()作为可空类型,以避免在
*返回null。
*/
fun any():T=Mockito.any()
/**
*返回ArgumentCaptor.capture()作为可空类型,以避免java.lang.IllegalStateException
*当返回null时。
*/
有趣的捕获(argumentCaptor:argumentCaptor):T=argumentCaptor.capture()

请参阅谷歌的Android架构蓝图库。

对于需要键入
any(type:Class)

private fun any(类型:Class):T=Mockito.any(类型)

这会起作用,类型检查也会发生

当您使用
Mockito.any()
时,它只需要返回一个非空结果

Mockito.any()?:0
Mockito.any()?:HashMap()
Mockito.any()?:{}

要扩展@makovkastar提供的答案,您可以提供如下可为空或不可为空的匹配器:

/**
 * Matcher that returns null
 */
private inline fun <reified T> any(): T = Mockito.any<T>()

/**
 * Matcher never returns null
 */
private inline fun <reified T> any(type: Class<T>): T = Mockito.any(type)
/**
*返回null的匹配器
*/
private inline fun any():T=Mockito.any()
/**
*Matcher从不返回null
*/
私有内联fun any(类型:Class):T=Mockito.any(类型)

kotlin社区网站上有一个关于如何避免此问题的讨论,请查看:谢谢。似乎devnet.jetbrains.com没有被谷歌很好地索引。我相信,我很好心地要求你也在你的答案中复制链接的内容,这样,如果链接死了,这个答案仍然有用。可悲的是,在1.0.0-beta-4584中,这种解决方法似乎不再有效:
kotlin.TypeCastException:null不能转换为非null类型X
@nhaarman非常适合我,你能告诉我确切的情况吗?它不适用于kotlin 1.2.40。没有其他解决办法吗?@nhaarman Kotlin 1.3.11、Mockito 2.7.12、Kotlin Mockito 1.5.0,2019年1月:解决办法1。。。嗯,它在周围起作用。我的用例在给定的/when子句中。看起来URL被移动到:非常感谢!使用最新版本的Mockito(v3.3.3)和Kotlin(v1.3.72)也可以避免在参数中使用具体化的参数传递ClassName::class.java:
inline fun anyNonNull():T=Mockito.any(T::class.java)
Mockito.any() ?: 0
Mockito.any() ?: HashMap<Int,Int>()
Mockito.any() ?: {}
/**
 * Matcher that returns null
 */
private inline fun <reified T> any(): T = Mockito.any<T>()

/**
 * Matcher never returns null
 */
private inline fun <reified T> any(type: Class<T>): T = Mockito.any(type)