可以在Kotlin中使用Mockito吗?

ato*_*tok 61 java mocking mockito kotlin

我面临的问题是Matchers.anyObject()回报null.当用于仅接受非可空类型的mock方法时,它会导致抛出"不应为null"异常.

`when`(mockedBackend.login(anyObject())).thenAnswer { invocationOnMock -> someResponse }
Run Code Online (Sandbox Code Playgroud)

模拟方法:

public open fun login(userCredentials: UserCredentials): Response
Run Code Online (Sandbox Code Playgroud)

Ser*_*kov 62

有两种可能的解决方法:

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 { ... }
}
Run Code Online (Sandbox Code Playgroud)

另一种解决方法是

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

@Test
fun myTest() {
    `when`(mockedBackend).login(anyObject())).thenAnswer { ... }
}
Run Code Online (Sandbox Code Playgroud)

以下是关于此主题的更多讨论,其中首先提出了解决方法.

  • 我相信你也要求你在你的答案中复制链接的内容,这样如果链接永远消失,这个答案仍然有用. (6认同)
  • 它不适用于Kotlin 1.2.40。还有其他解决方法吗? (2认同)

小智 21

对于那些需要打字的人 any(type: Class<T>)

    private fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
Run Code Online (Sandbox Code Playgroud)

这会工作,类型检查也会发生!

  • 使用具体化参数可以避免在参数中传递 *ClassName::class.java*: `inline fun &lt;reified T&gt; anyNonNull(): T = Mockito.any&lt;T&gt;(T::class.java)` (8认同)
  • 完美,就是不行 (2认同)

mak*_*tar 15

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

请参阅Google的Android Architecture Blueprints存储库中的MockitoKotlinHelpers.kt.

  • 网址似乎已移至:https://github.com/googlesamples/android-architecture/blob/todo-mvp-kotlin/todoapp/app/src/test/java/com/example/android/architecture/blueprints/ todoapp / MockitoKotlinHelpers.kt (2认同)

max*_*ron 9

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

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

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

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