Let's say I have the following two classes:
class Foo {
fun <RES> execute(callback: () -> RES): RES {
return callback.invoke()
}
}
class Bar(
private val foo: Foo,
) {
fun perform(): String {
return foo.execute {
"Hello World"
}
}
}
When testing Bar
I would like to mock the call to Foo#execute
I tried the following using MockK (expecting the test to print "Mock Answer"):
class BarTest {
private val foo: Foo = mockk()
private val bar = Bar(foo)
@Test
fun test() {
every {
foo.execute {
"Hello World"
}
}.answers {
"Mock Answer"
}
println(bar.perform())
}
}
However, I get the below exception:
io.mockk.MockKException: no answer found for Foo(#1).execute(lambda {}) among the configured answers: (Foo(#1).execute(eq(lambda {}))))
I imagine that this is happening because the callback is being created as an anonymous class and thus the two objects are different albeit both returning the string "Hello World", my question is there a way to actually accomplish this using MockK or otherwise?
Also, If I try to create one callback object such as val callback = { "Hello World" }
and then pass it to Foo#execute
in both Bar#perform
and the test, I get the expected result, however this is of course not going to work in a real scenario.
You can use Capturing slot to mock the lambda response
@Test
fun test() {
val slot = slot<() -> Any>()
every {
foo.execute (capture(slot))
}.answers {
"Mock Answer"// slot.captured.invoke()
}
assertEquals("Mock Answer", bar.perform())
}