I'm trying to use the mockk framework to set up a mock in one of my unit tests that executes a suspending function like this:
val executionCompletionSource = CompletableDeferred<Nothing>()
suspend fun task(): Unit = executionCompletionSource.await()
val mock = mockk<Executable> { coEvery { execute() } coAnswers { task() } }
However, I find that the test hangs indefinitely if I call mock.execute() in a launched coroutine scope. If I call task() directly within the launched scope instead, the test runs fine.
Although the mockk documentation does talk a little about coroutine mocking, I can't find any documentation or examples showing how to execute coroutines in response to calling a suspending function on a mock.
Here's an SSCCE demonstrating this:
package experiment
import io.mockk.coEvery
import io.mockk.mockk
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.system.measureTimeMillis
interface Executable {
    suspend fun execute()
}
fun main() {
    val executionCompletionSource = CompletableDeferred<Nothing>()
    suspend fun task(): Unit = executionCompletionSource.await()
    val mock = mockk<Executable> { coEvery { execute() } coAnswers { task() } }
    runBlocking {
        val execution = launch { mock.execute() } // This blocks the test indefinitely
        //val execution = launch { task() } // This works fine (~110-120 ms)
        measureTimeMillis {
            delay(100)
            executionCompletionSource.cancel()
            execution.join()
        }.also { elapsed -> println("Elapsed in $elapsed ms") }
    }
}
The following dependencies are used:
implementation(kotlin("stdlib-jdk8"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.0")
implementation("io.mockk:mockk:1.8.10.kotlin13")
 
                        
This seems to be bug with the way mockk handles coroutines - it's now being tracked here.
As a temporary workaround I'm manually creating mocks in cases where I need to mock suspend functions. For example: