Reputation: 17991
In Kotlin (and Java 8) we can use Lambda expression to remove boilerplate callback interface. For example,
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"))
}
}
We can change remove ProfileCallback
and change it into Kotlin's Lambda:
class ProfileRepository(val callback: (Profile) -> Unit) {
fun getProfile() {
// do calculation
callback(Profile("name"))
}
}
This works fine, but I'm not sure how to mock and then verify that function. I have tried using Mockito like this
@Mock
lateinit var profileCallback: (Profile) -> Unit
@Test
fun test() {
// this wouldn't work
Mockito.verify(profileCallback).invoke(any())
}
but it throw an Exception:
org.mockito.exceptions.base.MockitoException: ClassCastException occurred while creating the mockito mock : class to mock : 'kotlin.jvm.functions.Function1', loaded by classloader : 'sun.misc.Launcher$AppClassLoader@7852e922'
How to mock and verify Lambda expression in Kotlin? Is it even possible?
Upvotes: 8
Views: 8672
Reputation: 2211
Here is example how you can achieve that using mockito-kotlin
:
Given repository class
class ProfileRepository(val callback: (Int) -> Unit) {
fun getProfile() {
// do calculation
callback(1)
}
}
Using mockito-kotlin
lib - you can write test mocking lambdas like this:
@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)
}
}
Upvotes: 6