mockk: Bug: exception while calling mocked suspend function
In Version 1.9.3, calling a mocked suspending function throws “no answer found” even if an answer was provided.
val call = mockk<suspend () -> Int>()
coEvery { call() } returns 5
runBlocking { assertEquals(5, call()) } // throws MockKException below
- This works if the mocked function does not
suspend
. - A workaround is to wrap the suspending function in an interface (but it would be cleaner to be able to mock the suspending function directly.)
Here’s the exception:
io.mockk.MockKException: no answer found for: Function1(#8).invoke(continuation {})
at io.mockk.impl.stub.MockKStub.defaultAnswer(MockKStub.kt:90)
at io.mockk.impl.stub.MockKStub.answer(MockKStub.kt:42)
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:263)
at io.mockk.impl.instantiation.JvmMockFactoryHelper$mockHandler$1.invocation(JvmMockFactoryHelper.kt:25)
at io.mockk.proxy.jvm.advice.Interceptor.call(Interceptor.kt:20)
at io.mockk.proxy.jvm.advice.BaseAdvice.handle(BaseAdvice.kt:42)
at io.mockk.proxy.jvm.advice.jvm.JvmMockKProxyInterceptor.interceptNoSuper(JvmMockKProxyInterceptor.java:45)
at kotlin.jvm.functions.Function1$Subclass3.invoke(Unknown Source)
at ScopingStoreTest$put an item$1$2.invokeSuspend(ScopingStoreTest.kt:56)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:238)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.kt:116)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:79)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:53)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:35)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at MyTest$myTest$1.invokeSuspend(MyTest.kt:56)
...
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 25
- Comments: 29
Commits related to this issue
- - related to #288 — committed to mockk/mockk by oleksiyp 4 years ago
Any news on this bug ? I’m having the same bug mocking an object having a suspend function. Any workaround for this case ?
3rd birthday coming up, let’s throw a party. Who brings cake? It’s marked with Critical, Important, and Bug, better to remove those labels, looks like many users have been waiting for a fix all this time.
I think I am getting the same thing
In version 1.10.0 i am still getting the same error Exception in thread “main @coroutine#5” io.mockk.MockKException: no answer found for:
I am using Room db and calling its dao methods which are suspended
Example
interface TestDao{ suspend fun getValue():String{} }
class Test{ fun test(){ Globalscope.launch(Dispatchers.IO) { val value = db.testDao.getValue()}}
}
@Test class TestClass{ val testDao= mockk<TestDao>() coEvery { db.testDao() } returns testDao coEvery { testDao.getValue(“k1”, “s1”) } return “” }
Cannot really use this workaround @gladed is providing. I am mocking object that is injected via DI and that object’s suspend method has to return value. I cannot wrap anything within interfaces as it would mess up the production code.
I was injecting a suspending function through the constructor. A workaround is to declare a regular interface with an
invoke
function and pass a method reference to the object under test. Then the call side for the actual mocking stays identically.So for example my class under test had a function declared in the constructor:
As a workaround instead of mocking the suspending function
I created an interface:
and I’m passing a method reference:
Now at the mocking side the usage stays the same:
This is not how you should ask for an update on a github issue. Take notes, kids.
I’m having the same issue, any update?
I found some workaround - check if the actual last argument is a continuation, not just method types. Sad that more and more workarounds are needed, but I think anyway it has it’s value.