You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am currently running into the following problem and I'm a bit lost on how to solve this issue.
I have a basic application with a controller and service. Both are annotated for some AOP functionality. The application itself runs fine and AOP works as expected.
The problem arises during testing, when I want to mock my service bean to spy and verify its usage. This causes an StackOverflowError, I guess because the mock and AOP interceptor keep calling each other?
Stacktrace
java.lang.StackOverflowError: null
at java.base/java.lang.ref.Reference.refersToImpl(Reference.java:384)
at java.base/java.lang.ref.Reference.refersTo(Reference.java:375)
at java.base/java.lang.ThreadLocal$ThreadLocalMap.set(ThreadLocal.java:552)
at java.base/java.lang.ThreadLocal.set(ThreadLocal.java:265)
at java.base/java.lang.ThreadLocal.set(ThreadLocal.java:251)
at io.mockk.proxy.jvm.advice.SelfCallEliminatorCallable.call(SelfCallEliminatorCallable.kt:20)
at io.mockk.impl.instantiation.JvmMockFactoryHelper.handleOriginalCall(JvmMockFactoryHelper.kt:96)
at io.mockk.impl.instantiation.JvmMockFactoryHelper.access$handleOriginalCall(JvmMockFactoryHelper.kt:19)
at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1$invocation$1$1.invoke(JvmMockFactoryHelper.kt:28)
at io.mockk.impl.stub.MockKStub$handleInvocation$originalPlusToString$1.invoke(MockKStub.kt:235)
at io.mockk.impl.stub.SpyKStub.defaultAnswer(SpyKStub.kt:15)
at io.mockk.impl.stub.MockKStub.answer(MockKStub.kt:44)
at io.mockk.impl.recording.states.AnsweringState.call(AnsweringState.kt:16)
at io.mockk.impl.recording.CommonCallRecorder.call(CommonCallRecorder.kt:53)
at io.mockk.impl.stub.MockKStub.handleInvocation(MockKStub.kt:271)
at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invocation(JvmMockFactoryHelper.kt:24)
at io.mockk.proxy.jvm.advice.Interceptor.call(Interceptor.kt:21)
at com.example.$DemoServiceImpl$Definition$Intercepted.$$access$$getDemo(Unknown Source)
at com.example.$DemoServiceImpl$Definition$Exec.dispatch(Unknown Source)
at io.micronaut.context.AbstractExecutableMethodsDefinition$DispatchedExecutableMethod.invoke(AbstractExecutableMethodsDefinition.java:456)
at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:134)
at com.example.$DemoServiceImpl$Definition$Intercepted.getDemo(Unknown Source)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at io.mockk.proxy.jvm.advice.MethodCall.call(MethodCall.kt:14)
at io.mockk.proxy.jvm.advice.SelfCallEliminatorCallable.call(SelfCallEliminatorCallable.kt:14)
at io.mockk.impl.instantiation.JvmMockFactoryHelper.handleOriginalCall(JvmMockFactoryHelper.kt:96)
at io.mockk.impl.instantiation.JvmMockFactoryHelper.access$handleOriginalCall(JvmMockFactoryHelper.kt:19)
at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1$invocation$1$1.invoke(JvmMockFactoryHelper.kt:28)
at io.mockk.impl.stub.MockKStub$handleInvocation$originalPlusToString$1.invoke(MockKStub.kt:235)
at io.mockk.impl.stub.SpyKStub.defaultAnswer(SpyKStub.kt:15)
at io.mockk.impl.stub.MockKStub.answer(MockKStub.kt:44)
at io.mockk.impl.recording.states.AnsweringState.call(AnsweringState.kt:16)
at io.mockk.impl.recording.CommonCallRecorder.call(CommonCallRecorder.kt:53)
at io.mockk.impl.stub.MockKStub.handleInvocation(MockKStub.kt:271)
at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invocation(JvmMockFactoryHelper.kt:24)
at io.mockk.proxy.jvm.advice.Interceptor.call(Interceptor.kt:21)
at com.example.DemoServiceImpl.getDemo(DemoServiceImpl.kt:9)
at com.example.$DemoServiceImpl$Definition$Intercepted.$$access$$getDemo(Unknown Source)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at io.mockk.proxy.jvm.advice.MethodCall.call(MethodCall.kt:14)
I found a couple of workarounds but I'd like to understand the problem first, as all these would require some major refactoring of my existing code base and aren't applicable for all cases.
I can create the service class manually instead of getting it from the application context. But is also requires to inject all the dependencies for the service manually.
I can fully mockk the service. Requires writing a lot of additional code for mock behavior. Alternatively it also works if the mock delegates all calls to an injected DemoService bean.
I'll appreciate any ideas, feeback or workarounds.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Explanation
I am currently running into the following problem and I'm a bit lost on how to solve this issue.
I have a basic application with a controller and service. Both are annotated for some AOP functionality. The application itself runs fine and AOP works as expected.
The problem arises during testing, when I want to mock my service bean to spy and verify its usage. This causes an StackOverflowError, I guess because the mock and AOP interceptor keep calling each other?
Stacktrace
Minimal example
Environment info
AOP Annotation
Controller
Service
Test
Workarounds
I found a couple of workarounds but I'd like to understand the problem first, as all these would require some major refactoring of my existing code base and aren't applicable for all cases.
I can create the service class manually instead of getting it from the application context. But is also requires to inject all the dependencies for the service manually.
I can fully mockk the service. Requires writing a lot of additional code for mock behavior. Alternatively it also works if the mock delegates all calls to an injected DemoService bean.
I'll appreciate any ideas, feeback or workarounds.
Beta Was this translation helpful? Give feedback.
All reactions