Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No answer found for: ...continuation {}) #957

Open
2 of 3 tasks
igorwojda opened this issue Oct 28, 2022 · 8 comments
Open
2 of 3 tasks

No answer found for: ...continuation {}) #957

igorwojda opened this issue Oct 28, 2022 · 8 comments

Comments

@igorwojda
Copy link

igorwojda commented Oct 28, 2022

Prerequisites

Please answer the following questions for yourself before submitting an issue.

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed

Expected Behavior

Mockk handles the implicit continuation parameter

Current Behavior

Method mock is not working

Failure Information (for bugs)

Exception in thread "Test worker @coroutine#4" io.mockk.MockKException: no answer found for:
GetAlbumUseCase(#1).execute(Thriller, Michael Jackson, 123, continuation {})

Steps to Reproduce

I could not extract this issue into a self-contained code sample, however, I have created a dedicated branch in my project where you can quickly reproduce this issue:

https://github.com/igorwojda/android-showcase/tree/mockk-continuation-no-answear-bug

  1. Open AlbumDetailViewModelTest class
  2. Remove @Disabled("mockk can't correctly mock this function") annotation
  3. Run the onEnter album is not found test

Context

Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions.

  • MockK version: "1.13.2"
  • OS: MacOs BigSur / Ventura
  • Kotlin version: 1.7.20
  • JDK version: openjdk 19 2022-09-20
  • JUnit version: 5.9.1
  • Type of test: unit test OR android instrumented test: Unit test

Stack trace

Exception in thread "Test worker @coroutine#4" io.mockk.MockKException: no answer found for: GetAlbumUseCase(#1).execute(Thriller, Michael Jackson, 123, continuation {})
	at io.mockk.impl.stub.MockKStub.defaultAnswer(MockKStub.kt:93)
	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: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.igorwojda.showcase.feature.album.domain.usecase.GetAlbumUseCase.execute(GetAlbumUseCase.kt:15)
	at com.igorwojda.showcase.feature.album.presentation.screen.albumdetail.AlbumDetailViewModel$getAlbum$1.invokeSuspend(AlbumDetailViewModel.kt:31)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.test.TestDispatcher.processEvent$kotlinx_coroutines_test(TestDispatcher.kt:28)
	at kotlinx.coroutines.test.TestCoroutineScheduler.tryRunNextTaskUnless$kotlinx_coroutines_test(TestCoroutineScheduler.kt:100)
	at kotlinx.coroutines.test.TestCoroutineScheduler.advanceUntilIdleOr$kotlinx_coroutines_test(TestCoroutineScheduler.kt:120)
	at kotlinx.coroutines.test.TestCoroutineScheduler.advanceUntilIdle(TestCoroutineScheduler.kt:113)
	at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt.runTestCoroutine(TestBuilders.kt:237)
	at kotlinx.coroutines.test.TestBuildersKt.runTestCoroutine(Unknown Source)
	at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTest$1$1.invokeSuspend(TestBuilders.kt:167)
	at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTest$1$1.invoke(TestBuilders.kt)
	at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTest$1$1.invoke(TestBuilders.kt)
	at kotlinx.coroutines.test.TestBuildersJvmKt$createTestResult$1.invokeSuspend(TestBuildersJvm.kt:13)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
	at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
	at kotlinx.coroutines.test.TestBuildersJvmKt.createTestResult(TestBuildersJvm.kt:12)
	at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt.runTest(TestBuilders.kt:166)
	at kotlinx.coroutines.test.TestBuildersKt.runTest(Unknown Source)
	at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt.runTest(TestBuilders.kt:154)
	at kotlinx.coroutines.test.TestBuildersKt.runTest(Unknown Source)
	at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt.runTest$default(TestBuilders.kt:147)
	at kotlinx.coroutines.test.TestBuildersKt.runTest$default(Unknown Source)
	at com.igorwojda.showcase.feature.album.presentation.screen.albumdetail.AlbumDetailViewModelTest.onEnter album is not found(AlbumDetailViewModelTest.kt:27)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
	at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy2.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
	Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [CoroutineId(4), "coroutine#4":StandaloneCoroutine{Cancelling}@340d6d89, Dispatchers.Main]

Expected: <com.igorwojda.showcase.feature.album.presentation.screen.albumdetail.AlbumDetailViewModel$UiState$Error@37854b34> but was: <com.igorwojda.showcase.feature.album.presentation.screen.albumdetail.AlbumDetailViewModel$UiState$Loading@2ddb3ae8>
Expected :com.igorwojda.showcase.feature.album.presentation.screen.albumdetail.AlbumDetailViewModel$UiState$Error@37854b34
Actual   :com.igorwojda.showcase.feature.album.presentation.screen.albumdetail.AlbumDetailViewModel$UiState$Loading@2ddb3ae8
@aschugunov
Copy link

aschugunov commented Nov 4, 2022

I got the same error with the example
kotlin 1.5.30
mockk 1.11.0
kotlinx-coroutines-core-jvm: 1.5.2

import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Test
import org.springframework.web.reactive.function.client.WebClient
import org.springframework.web.reactive.function.client.awaitBodilessEntity

internal class ExampleTest {

    @Test
    fun test(): Unit = runBlocking {
        val dep = mockk<Dep>()
        val example = Example(dep)
        val entity = mockk<Entity>()
        every { entity.param1 } returns 5
        every { entity.param2 } returns 56
        coEvery { dep.func1(entity.param1, entity.param2) } returns "mockk answer dep func1"

        val res = example.exampleTest(entity)

        coVerify(exactly = 1) { dep.func1(entity.param1, entity.param2) }
        assert(res == "example test complete")
    }

    class Example(
        private val dep: Dep,
    ) {
        suspend fun exampleTest(entity: Entity): String {
            dep.func1(entity.param1, entity.param2)
            return "example test complete"
        }
    }

    class Dep(
        private val webClient: WebClient,
    ) {
        suspend fun func1(param1: Int, param2: Long): String {
            println("this is params: $param1 $param2")
            webClient.get().uri("/localhost").retrieve().awaitBodilessEntity()
            return "dep func1 complete"
        }
    }

    data class Entity(
        val param1: Int,
        val param2: Long,
    )
}

log

08:49:05.903 [Test worker @coroutine#1] DEBUG io.mockk.impl.instantiation.AbstractMockFactory - Creating mockk for Dep name=#1
08:49:06.282 [Test worker @coroutine#1] DEBUG io.mockk.impl.instantiation.AbstractMockFactory - Creating mockk for Entity name=#2
08:49:07.429 [Test worker @coroutine#1] DEBUG io.mockk.impl.instantiation.AbstractMockFactory - Creating mockk for Any name=child of #1#3
08:49:07.435 [Test worker @coroutine#1] DEBUG io.mockk.impl.recording.states.AnsweringState - Answering 5 on Entity(#2).getParam1()
08:49:07.436 [Test worker @coroutine#1] DEBUG io.mockk.impl.recording.states.AnsweringState - Answering 56 on Entity(#2).getParam2()
08:49:07.439 [Test worker @coroutine#1] DEBUG io.mockk.impl.recording.states.AnsweringState - Throwing io.mockk.MockKException: no answer found for: Dep(#1).func1(5, 56, continuation {}) on Dep(#1).func1(5, 56, continuation {})

no answer found for: Dep(#1).func1(5, 56, continuation {})
io.mockk.MockKException: no answer found for: Dep(#1).func1(5, 56, continuation {})
	at app//io.mockk.impl.stub.MockKStub.defaultAnswer(MockKStub.kt:90)
	at app//io.mockk.impl.stub.MockKStub.answer(MockKStub.kt:42)
	at app//io.mockk.impl.recording.states.AnsweringState.call(AnsweringState.kt:16)
	at app//io.mockk.impl.recording.CommonCallRecorder.call(CommonCallRecorder.kt:53)
	at app//io.mockk.impl.stub.MockKStub.handleInvocation(MockKStub.kt:263)
	at 

In my case solution was

val entity = Entity(5, 56)
coEvery { dep.func1(entity.param1, entity.param2) } returns "mockk answer dep func1"

It seems usage of mock entity and then pass their properties in method arguments produces such error.

@deepakkumar-mahindra
Copy link

@igorwojda I am facing the same issue and have not solved yet. have you solved this issue?

@igorwojda
Copy link
Author

igorwojda commented May 12, 2023

Not solved

@deepakkumar-mahindra
Copy link

Not solved

okay

@lorthirk
Copy link

Same for me, mockk 1.13.5.

@deepakkumar-mahindra
Copy link

@igorwojda The issue is with the Dispatcher rule made for suspend functions. working fine for me.

use the below code and define this rule into your viewmodel test class.

@OptIn(ExperimentalCoroutinesApi::class)
class MainDispatcherRule(
private val testDispatcher: TestDispatcher = UnconfinedTestDispatcher()
) : TestWatcher() {

override fun starting(description: Description) {
    super.starting(description)
    Dispatchers.setMain(testDispatcher)
}

override fun finished(description: Description) {
    super.finished(description)
    Dispatchers.resetMain()
}

}

@igorwojda
Copy link
Author

@deepakkumar-mahindra you are using JUnit4.
I am already using an equivalent Extension for JUnit5 and I am experiencing this the issue:
https://github.com/igorwojda/android-showcase/blob/main/library_test_utils/src/main/kotlin/com/igorwojda/showcase/library/testutils/CoroutinesTestDispatcherExtension.kt

@RobotEmilio
Copy link

My experience with this has been weird, but I want to share in case is useful for somebody:
Basically i was having the same error than reported in this issue. I was actually being shown two errors, this one and one after that I thought was caused by the continuation() thing (an assertion of intent failing, thinking it was returning default value).
However when I fixed the assertion of the second error, the test ended up working OK and the continuation issue ended up posing no problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants