1

I want to test this function.

suspend fun fetchTwoDocs() =
        coroutineScope {
            val deferredOne = async { fetchDoc(1) }
            val deferredTwo = async { fetchDoc(2) }
            deferredOne.await()
            deferredTwo.await()
        }

How to test this function in mockk

Kotlin Learner
  • 3,995
  • 6
  • 47
  • 127
  • 1
    Do you want to test this function or to mock this function? – Joffrey Nov 11 '21 at 11:43
  • I need both @Joffrey – Kotlin Learner Nov 11 '21 at 12:03
  • It would be nice if you could be a bit more specific about what you want to do exactly. Do you want to stub `fetchDoc` and test `fetchTwoDocs`? Or verify some calls? Please share your test code that you would have written if the function was not suspend, and point out what doesn't work when you try it with suspend functions. It will be much easier to help you this way. – Joffrey Nov 11 '21 at 12:30
  • Also, the function you wrote only returns the value of the second call, is that intended? If that's on purpose, you don't need to `await()` the first one (`coroutineScope` already awaits child coroutines) – Joffrey Nov 11 '21 at 12:30
  • @Joffrey I want to test the function with stub the call and also verify. I am new to the testing. I don't know how to start and stub all these functiom. – Kotlin Learner Nov 11 '21 at 12:36
  • Then I believe you should start by reading the documentation of the testing framework you want to use. StackOverflow is meant for specific questions, so the answers are focused on one problem. Here the phrasing of your question correctly matches SO's expectations - it's somewhat specific. It's about using Mockk with async functions (even though it could be more specific). But it seems your actual question is "how to test" in general, and for this, SO is not very well suited. – Joffrey Nov 11 '21 at 12:40

2 Answers2

1

I'm assuming you can't or won't rewrite the code you are writing to use coroutines. In that case, Pablisco offered great ideas here. The one I liked the best was using a queue:

// You create a sync queue
val queue = SynchronousQueue<String>() // Or the type of 'fetch2Docs'
// fetchTwoDocs runs async so it will return eventually
queue.put(fetchTwoDocs())
// queue.take() will wait until there is a value in the queue
assertThat(queue.take(), equalTo("expected value"))

Here an extra example on how to use this in an hypothetical async callback:

val queue = SynchronousQueue<String>()
asyncFunctionThatReturnsWithCallback(someParam) { callbackParam ->
    queue.put(callbackParam)
}
assertTrue(queue.take())
El Marce
  • 3,144
  • 1
  • 26
  • 40
0

If you just want to test the function, you can simply call it inside runBlocking from your test, or use the kotlinx-coroutines-test library which provides runBlockingTest:

@Test
fun test() = runBlocking {
    val result = fetchTwoDocs()
    // then assert stuff
}
Joffrey
  • 32,348
  • 6
  • 68
  • 100