How can you use `Mockito ArgumentCaptor` to capture and test Kotlin higher-order function arguments?

In Kotlin, ArgumentCaptor works well for capturing interface-based callbacks, such as when using an interface like Callback with a done() method. However, when refactoring the same logic to use a higher-order function like doSomeThing(done: () -> Unit), it becomes unclear how to capture and invoke that function using Mockito’s ArgumentCaptor. The question focuses on how to properly define the captor type (e.g., ArgumentCaptor.forClass(???)) for Kotlin function parameters and how to trigger the captured lambda within tests to verify behavior.

I’ve bumped into this a few times over the years, so here’s how I usually handle it.

In Kotlin, higher-order functions are really just instances of Function0, Function1, etc., under the hood. So if you’re trying to capture a lambda like done: () -> Unit, you can set up your Mockito ArgumentCaptor like this:

val captor = ArgumentCaptor.forClass(Function0::class.java) as ArgumentCaptor<() -> Unit>

verify(mock).doSomething(captor.capture())


captor.value.invoke()

It works cleanly because Kotlin compiles lambdas into the proper FunctionX interfaces. This is one of the simpler patterns I rely on when dealing with argumentcaptor kotlin scenarios.

Yeah, same here after working with this pattern across a few codebases, one thing I’d add is…

@ishrth_fathima’s approach is spot-on, and it scales neatly when your lambda takes parameters. Just remember that the Function type changes based on the lambda signature. For example:

  • () -> UnitFunction0<Unit>
  • (id: Int) -> BooleanFunction1<Int, Boolean>
  • (a: String, b: Int) -> UnitFunction2<String, Int, Unit>

Once you match the correct FunctionX type, capturing works exactly the same:

val captor = ArgumentCaptor.forClass(Function1::class.java) 
        as ArgumentCaptor<(Int) -> Boolean>

verify(mock).process(captor.capture())

// Trigger it
captor.value.invoke(42)

This keeps things predictable when applying argumentcaptor kotlin patterns with various lambda shapes.

Adding to @Ambikayache’s point after working with Mockito for a while, I found a cleaner way that avoids the manual casting entirely.

If you want a more Kotlin-friendly approach, Mockito-Kotlin’s argumentCaptor() helper is a lifesaver. It handles generics properly, avoids raw Function0 juggling, and keeps the test readable:

val captor = argumentCaptor<() -> Unit>()

verify(mock).doSomething(captor.capture())

// Invoke the captured lambda
captor.firstValue.invoke()

It’s a lot more idiomatic, and you avoid the risk of mismatched casts when dealing with argumentcaptor kotlin usage in higher-order function tests.