In the MWE below I'm trying to verify that calling baz()
also calls a method on another object. However, I can't seem to mock / spy on that object.
MWE:
package com.example
import io.mockk.every
import io.mockk.mockkStatic
import io.mockk.spyk
import io.mockk.verify
import org.junit.jupiter.api.Test
class FooBarTest {
@Test
fun `top level fun baz() calls theVal_bar()`() {
mockkStatic("com.example.FooBarTestKt")
val spy = spyk(theVal, name = "Hello, Spy!")
every { theVal } returns spy
// Should call bar() on the spy, but note that the spy's name is not printed
baz()
verify { spy.bar() }
}
}
class Foo
fun Foo.bar() = println("Foo.bar! name = $this")
val theVal = Foo()
fun baz() = theVal.bar()
This fails, because the call to theVal.bar()
gets the val
initialiser value instead of the mocked value spy
.
How can I enforce the spy being used without changing the top level property definitions? In other words: I need a top level 'constant', but I want to mock it too. I could use val theVal get() = Foo()
, which solves the issue, but it changes the code significantly, as it would replace the Foo
instance every time.
Versions used: - Kotlin 1.3.10 - MockK 1.8.13.kotlin13 - JUnit 5.3.1
The error:
java.lang.AssertionError: Verification failed: call 1 of 1: class com.example.FooBarTestKt.bar(eq(Foo(Hello, Spy!#1)))). Only one matching call to FooBarTestKt(static FooBarTestKt)/bar(Foo) happened, but arguments are not matching:
[0]: argument: com.example.Foo@476b0ae6, matcher: eq(Foo(Hello, Spy!#1)), result: -