# mockk

Mykola Gurov

11/14/2021, 2:27 PM
Hi, I'm stuck trying to nail down the root cause of this issue . There I wrap a Spring-managed bean as a Mockk's spy and inject back to the spring context as a
bean - a convenient technique to spy on Beans and inject "strange" behaviors. All works good till we hit Spring AOP-proxied beans, e.g
in my example. Some funky interactions are happening there and we end up seeing this exception 🧵:
Copy code
Caused by: io.mockk.MockKException: no answer found for: TargetSource(child of #1#2).getTarget()
	at io.mockk.impl.stub.MockKStub.defaultAnswer(MockKStub.kt:93) ~[mockk-1.12.0.jar:na]
	at io.mockk.impl.stub.MockKStub.answer(MockKStub.kt:42) ~[mockk-1.12.0.jar:na]
	at ~[mockk-1.12.0.jar:na]
	at ~[mockk-1.12.0.jar:na]
	at io.mockk.impl.stub.MockKStub.handleInvocation(MockKStub.kt:266) ~[mockk-1.12.0.jar:na]
	at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invocation(JvmMockFactoryHelper.kt:23) ~[mockk-1.12.0.jar:na]
	at ~[mockk-agent-jvm-1.12.0.jar:na]
	at io.mockk.proxy.jvm.advice.BaseAdvice.handle(BaseAdvice.kt:42) ~[mockk-agent-jvm-1.12.0.jar:na]
	at io.mockk.proxy.jvm.advice.jvm.JvmMockKProxyInterceptor.interceptNoSuper( ~[mockk-agent-jvm-1.12.0.jar:na]
	at org.springframework.aop.TargetSource$Subclass0.getTarget(Unknown Source) ~[spring-aop-5.3.12.jar:5.3.12]
This doesn't look very good to me as I'd expect spies to be transparent for non-preprogrammed calls, but instead I can reproduce the situation with
Copy code
class Service() {

    fun respondCached(input: String) = prefix + "_" +


class InjectSpiesConfiguration {
    fun spiedService(service: Service): Service {
        val spyk = spyk(service)
        return spyk

class MockkSpykingTest(
    @Autowired private val spiedService: Service
) {

    fun `hardcoded unwrapping`() {
        //NB: no failures when the following line is commented.
        every { spiedService.respondCached("empty") } returns ""

        val firstUnwrap = (spiedService as Advised)
        val secondUnwrap = (firstUnwrap as Advised)

        SoftAssertions.assertSoftly {

Now, I understand that wrapping AOP'ed bean with spyk is probably not the best of the ideas and we should rather unwrap it first (e.g.
) but still - why does the mock's spy fails that invocation instead of preserving transparent behavior for non-intercepted calls?

Mattia Tommasone

11/14/2021, 9:16 PM
thanks for the detailed explanation 🙂 this looks pretty nasty indeed - my first guess would be that somehow AOP’s class decoration is being performed after the one done by mockk’s spy, so somehow mockk is convinced there is no answer defined for the method you are trying to invoke because it was added later by AOP. I don’t really know if this is the actual cause nor if there is a way to change the order to make sure mockk always does its magic last (and i don’t even know if it would be right), but it looks like a bug indeed.

Mykola Gurov

11/15/2021, 4:54 PM