Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito ArgumentCaptor for Kotlin function

Tags:

mockito

kotlin

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(???)

like image 592
fweigl Avatar asked Aug 02 '16 08:08

fweigl


People also ask

What is the use of ArgumentCaptor in mockito?

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.

What is ArgumentCaptor Forclass?

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.

How do you capture an argument in MockK?

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.

What does argument capture do?

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.


1 Answers

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()) 
like image 86
mfulton26 Avatar answered Sep 21 '22 04:09

mfulton26