https://kotlinlang.org logo
#coroutines
Title
# coroutines
j

jean

03/14/2023, 12:52 PM
I have the following code and I want to make sure the callback is unregistered. How can I trigger
awaitClose
from my unit test ? I tried to cancel
testScope
but that triggers a
ClosedReceiveChannelException: Channel was closed
since turbine gets also canceled.
Copy code
private fun someApiCallbackToFlow(api: API) = callbackFlow {
    val callback = object : ApiCallback {
        override fun next(data: Int) {
            trySend("Success")
        }
    }
    api.register(callback)
    awaitClose {
        println("callback unregistered")
        api.unregister(callback)
    }
}


@OptIn(ExperimentalTime::class)
@Test
fun test() = testScope.runTest {
    val api = SomeApi()
    val flow = someApiCallbackToFlow(api)
    flow.test {
        assertEquals(1, api.callbacks.size)
        api.getData()
        assertEquals("Success", awaitItem())
        // how can I check there isn't any callback here?
    }
}
You can launch a new coroutine to run the turbine
test
And then just cancel it , join, and verify the api unregister method was called
Copy code
runTest {
  coroutineScope {
    launch {
      flow.test {
        …
        cancel()
      }
    }
  }
  // verify unregister
}
Actually launching a new coroutine isn’t even necessary because the .test turbine API launches its own coroutine so:
Copy code
runTest {
  var called = false
  callbackFlow<Nothing> {
    awaitClose { called = true }
  }.test {
    cancel()
  }
  assertTrue(called)
}
This passes
j

jean

03/15/2023, 8:05 AM
It worked, thanks!
6 Views