3

I have a Kotlin class (The problem was simplified to have a basic example), in it there is a method testedMethod() I want to test interactions on.

I want to make sure the correct parameter is passed to anotherMethod(), my problem is that the parameter is not a value but a lambda function.

A simple solution in Kotlin is what I am looking for, it may or may not be based on this solution for java.

class TestedClass {

    fun testedMethod() {
        anotherMethod({ passedMethod() })
    }

    fun passedMethod() {}

    fun anotherMethod(lambdaParameter: () -> Unit) {
        // Does something with lambdaParameter
    }
}
Sebastian
  • 2,896
  • 23
  • 36
  • 1
    If lambda is used/called within `anotherMethod` then mock `passedMethod`. After which you exercise `testedMethod` and then verify that the mocked `passedMethod` was invoked. – Nkosi Mar 23 '18 at 17:10

2 Answers2

3

This is the solution I ended up using.

Basically you create a spy of the tested class to be able to verify its own method, and you use argumentCaptor to capture the passed lambda and be able to invoke what is in it.

import com.nhaarman.mockito_kotlin.argumentCaptor
import com.nhaarman.mockito_kotlin.spy
import com.nhaarman.mockito_kotlin.verify

@Test
fun lambdaParameterPassedIsCorrect() {
    val testedClass = TestedClass()
    val spyOfTestedClass = spy(testedClass)

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

    spyOfTestedClass.testedMethod()

    verify(spyOfTestedClass).anotherMethod(captor.capture())
    // Invoke the function passed as a parameter 
    // and then verify that the expected method was called
    val function = captor.firstValue
    function.invoke()
    verify(spyOfTestedClass).passedMethod()
}

I would still be interested in a simpler solution.

Sebastian
  • 2,896
  • 23
  • 36
  • I try to implement my case based on your answer but failed, for example val captor = argumentCaptor<() -> Unit>() -- give me an error – Alexey Simchenko Feb 26 '21 at 13:00
-1

You can use mockito_kotlin library, which have the function "verify".

  verify(TestedClass, times(1)).anotherMethod(eq(passedMethod))

Which verify that the method "anotherMethod" of class "TestedClass" invoked once with the parameter equal to "passedMethod"

  • 1
    Could you please provide a code example with the complete syntax that compiles and where the test passes? I thought it would be that easy before posting this question ;) – Sebastian Mar 26 '18 at 09:50