Consider a function that takes an interface implementation as an argument like this:
interface Callback { fun done() } class SomeClass { fun doSomeThing(callback: Callback) { // do something callback.done() } }
When I want to test the caller of this function, I can do something like
val captor = ArgumentCaptor.forClass(Callback::class) Mockito.verify(someClass).doSomeThing(captor.capture())
To test what the other class does when the callback is invoked, I can then do
captor.value.done()
Question: How can I do the same if I replace the callback interface with a high order function like
fun doSomeThing(done: () -> Unit) { // do something done.invoke() }
Can this be done with ArgumentCaptor and what class do I have to use in ArgumentCaptor.forClass(???)
Mockito ArgumentCaptor is used to capture arguments for mocked methods. ArgumentCaptor is used with Mockito verify() methods to get the arguments passed when any method is called. This way, we can provide additional JUnit assertions for our tests.
public class ArgumentCaptor<T> extends Object. Use it to capture argument values for further assertions. Mockito verifies argument values in natural java style: by using an equals() method. This is also the recommended way of matching arguments because it makes tests clean & simple.
MockK has a similar utility called a CapturingSlot . The functionality is very similar to Mockito, but the usage is different. Rather than calling the method argumentCaptor. capture() to create a argument matcher, you wrap the slot in a capture() function.
ArgumentCaptor allows us to capture an argument passed to a method to inspect it. This is especially useful when we can't access the argument outside of the method we'd like to test.
I recommend nhaarman/mockito-kotlin: Using Mockito with Kotlin
It solves this through an inline function with a reified type parameter:
inline fun <reified T : Any> argumentCaptor() = ArgumentCaptor.forClass(T::class.java)
Source: mockito-kotlin/ArgumentCaptor.kt at a6f860461233ba92c7730dd42b0faf9ba2ce9281 · nhaarman/mockito-kotlin
e.g.:
val captor = argumentCaptor<() -> Unit>() verify(someClass).doSomeThing(captor.capture())
or
val captor: () -> Unit = argumentCaptor() verify(someClass).doSomeThing(captor.capture())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With