How to call a lambda callback with mockk

You can use answers:

val otm: ObjectToMock = mockk()
every {  otm.methodToCall(any(), any())} answers {
    secondArg<(String) -> Unit>().invoke("anything")
}

otm.methodToCall("bla"){
    println("invoked with $it") //invoked with anything
}

Within the answers scope you can access firstArg, secondArg etc and get it in the expected type by providing it as a generic argument. Note that I explicitly used invoke here to make it more readable, it may also be omitted.


Maybe not exactly what you ask about, but you can use the funciton type for the mock:

val observerMock = mockk<(State) -> Unit>()

I had to look for a bit more example for the callback and found some example in Kotlin Test with Mockk. In my case, it's a bit more specific. I wanted to check and mock the onFailure and onSuccess case of a a custom callback implementation MyCustomCallback implementing the ListenableFutureCallback.

The code would look like that for my ExampleProducer class that would have a send function:

fun send(data: String) {
    val responseFuture = kafkaTemplate.send(topic, data)
    responseFuture.addCallback(MyCustomCallback())
}

So here who would the test go:

@Test
fun onFailureTest() {
    kafkaTemplate: KafkaTemplate<String, String> = mockk()
    val captureCallback = slot<ListenableFutureCallback<SendResult<String, String>>>()
    
    every { callback.addCallback(capture(captureCallback)) } answers {
               captureCallback.captured.onFailure(Throwable())
    }
    every { kafkaTemplate.send(any()) } returns callback
    
    val prod: ExampleProducer = ExampleProducer()
    prod.send("test")
    
    // Then you can verify behaviour or check your captureCallback.captured
    verify { kafkaTemplate.send(any()) }
    assertNotNull(captureCallback.captured)
}