Reputation: 149
Today I stumbled across a situation which I do not understand, possibly because of lack of insight into how mockito and mockito-kotlin work internally.
Given the code below, from my Kotlin beginner perspective, I have two pretty similar interface-methods. One returns Boolean, one String. Both are suspend functions in my example as in my real world situation my functions are too.
class ITestInterface {
suspend fun returnBoolean(): Boolean {
return true
}
suspend fun returnSomeString() : String {
return "String"
}
}
@Test
fun demoTest() {
val implMock = mock<ITestInterface> {
on {
runBlocking {
returnSomeString()
}
} doReturn "Hello"
on {
runBlocking {
returnBoolean()
}
} doReturn false
}
}
My observation is, when I run the test, like depicted above, I get the following error Message
com.nhaarman.mockitokotlin2.MockitoKotlinException: NullPointerException thrown when stubbing.
This may be due to two reasons:
- The method you're trying to stub threw an NPE: look at the stack trace below;
- You're trying to stub a generic method: try `onGeneric` instead.
at com.nhaarman.mockitokotlin2.KStubbing.on(KStubbing.kt:72)
at com.rewedigital.fulfillment.picking.components.substitute.DemoTest.demoTest(DemoTest.kt:30)
[...]
Experiments showed that
Could anybody explain why this is happening? To what extend do we have to do with generics here? And what would be the correct way of solving the issue in our real application? Having a bunch of on {} and some onGeneric {} ?
Thanks for your help!
Upvotes: 4
Views: 2126
Reputation: 1092
You should use the onBlocking method to properly mock the suspend function
Please try the following code:
@Test
fun demoTest() {
val implMock = mock<ITestInterface> {
onBlocking {
returnSomeString()
} doReturn "Hello"
onBlocking {
returnBoolean()
} doReturn false
}
runBlocking {
// Execute your code here
assertThat(implMock.returnSomeString()).isEqualTo("Hello")
assertThat(implMock.returnBoolean()).isEqualTo(false)
}
}
Upvotes: 1