可以在Kotlin中使用Mockito吗?

时间:2015-05-18 13:58:34

标签: java mocking mockito kotlin

我遇到的问题是Matchers.anyObject()返回null。当用于模拟仅接受非可空类型的方法时,它会导致"不应为null"被抛出的异常。

`when`(mockedBackend.login(anyObject())).thenAnswer { invocationOnMock -> someResponse }

模拟方法:

public open fun login(userCredentials: UserCredentials): Response

6 个答案:

答案 0 :(得分:51)

有两种可能的解决方法:

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 <T> anyObject(): T {
    return Mockito.anyObject<T>()
}

@Test
fun myTest() {
    `when`(mockedBackend).login(anyObject())).thenAnswer { ... }
}

此主题为some more discussion,首先建议解决方法。

答案 1 :(得分:14)

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

的人
    private fun <T> any(type: Class<T>): T = Mockito.any<T>(type)

这样可行,类型检查也会发生!

答案 2 :(得分:9)

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

要做到这一点,仍然避免NPE,你可以使用kotlin的elvis操作员。 例如: verify(mock).func(same(my_obj) ?: my_obj)

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

我偶然发现的另一件事是mockito-kotlin库,它解决了这个问题 https://github.com/nhaarman/mockito-kotlin

答案 3 :(得分:8)

您可以使用以下帮助函数在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()

请参阅Google的Android体系结构蓝图存储库中的MockitoKotlinHelpers.kt

答案 4 :(得分:2)

使用Mockito.any()时只需要返回非空结果;

Mockito.any() ?: 0
Mockito.any() ?: HashMap<Int,Int>()
Mockito.any() ?: {}

...

答案 5 :(得分:0)

要扩展@makovkastar提供的答案,您可以提供一个可为空或不可为空的Matcher,如下所示:

/**
 * 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)