如何在 Kotlin 中模拟和验证 Lambda 表达式?

ald*_*dok 5 testing lambda mockito kotlin

在 Kotlin(和 Java 8)中,我们可以使用 Lambda 表达式来移除样板回调接口。例如,

data class Profile(val name: String)

interface ProfileCallback {
  fun onSuccess(profile: Profile)
}

class ProfileRepository(val callback: ProfileCallback) {

  fun getProfile() {
    // do calculation
    callback.onSuccess(Profile("name"))
  }
}
Run Code Online (Sandbox Code Playgroud)

我们可以把removeProfileCallback改成Kotlin的Lambda:

class ProfileRepository(val callback: (Profile) -> Unit) {

  fun getProfile() {
    // do calculation
    callback(Profile("name"))
  }
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但我不确定如何模拟然后验证该功能。我试过像这样使用 Mockito

@Mock
lateinit var profileCallback: (Profile) -> Unit

@Test
fun test() {
    // this wouldn't work
    Mockito.verify(profileCallback).invoke(any())   
}
Run Code Online (Sandbox Code Playgroud)

但它抛出一个异常:

org.mockito.exceptions.base.MockitoException: ClassCastException 在创建 mockito 模拟时发生:要模拟的类:'kotlin.jvm.functions.Function1',由类加载器加载:'sun.misc.Launcher$AppClassLoader@7852e922'

如何在 Kotlin 中模拟和验证 Lambda 表达式?甚至有可能吗?

Ole*_*nko 5

以下是如何使用以下方法实现这一目标的示例mockito-kotlin

给定存储库类

class ProfileRepository(val callback: (Int) -> Unit) {

    fun getProfile() {
        // do calculation
        callback(1)
    }
}
Run Code Online (Sandbox Code Playgroud)

使用mockito-kotlinlib - 您可以编写测试模拟 lambda,如下所示:

@Test
fun test() {
    val callbackMock: (Int) -> Unit = mock()
    val profileRepository = ProfileRepository(callbackMock)

    profileRepository.getProfile()

    argumentCaptor<Int>().apply {
        verify(callbackMock, times(1)).invoke(capture())
        assertEquals(1, firstValue)
    }
}
Run Code Online (Sandbox Code Playgroud)