mockito / mockito-kotlin

Using Mockito with Kotlin
MIT License
3.11k stars 202 forks source link

Support suspend blocks in Answers #346

Closed mhernand40 closed 3 years ago

mhernand40 commented 5 years ago

When testing coroutines, I'd like to be able to mock a dependency with a suspend function with a custom Answer such that it delays, suspends indefinitely, or has other custom behavior besides simply returning a value. The particular test case I have in mind is testing that when the CoroutineScope of the class under test gets cancelled while one of its dependencies is suspending, it properly cancels the dependency and avoids further execution.

Example:

runBlocking {
    whenever(repository.loadStatus()).willAnswer {
        // Suspend indefinitely
        suspendCancellableCoroutine<Status> {} <-- Compiler error 'Suspension functions can be called only within coroutine body'
    }
}

or

mock<Repository> {
    onBlocking {
        loadStatus()
    } doAnswer {
        // Suspend indefinitely
        suspendCancellableCoroutine {} <-- Compiler error 'Suspension functions can be called only within coroutine body'
    }
}

MockK currently supports something like this with:

coEvery {
    repository.loadStatus()
} coAnswers {
    // Suspend indefinitely
    suspendCancellableCoroutine<Status> {}
}

Testing asynchronous coroutines code is now achievable with the latest version of https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/.

neworld commented 5 years ago

Made a PR: #357