How would you test this? ```class Syncer(private ...
# coroutines
u
How would you test this?
Copy code
class Syncer(private val db: Db) {
   private val scope = CoroutineScope(SupervisorJob + Dispatchers Io)
   
   fun sync() {
      scope.launch {
         ...
         db.insertSomething()
      }
   }
}
I'd like to assert that
db.readSomething()
reads what it should after I call
Syncer.sync()
There is nothing to suspend on to know when the sync actually finished (like some status flow) Is injecting
Dispatchers.Undispatched
instead of
Io
to make it synchronous, so I can assert right after
sync()
returns, idiomatic? Is there something better?
k
Best practice is to inject the dispatcher, which will make it easier to test https://developer.android.com/kotlin/coroutines/coroutines-best-practices#inject-dispatchers
u
what does that mean? I agree with the statement in general, but why would you inject testdispatcher if you dont need to control time & the public function is suspending so you can block on it the docs say to make it determnistic, not synchronous, i.e. Undispatched
s
It's either injecting the dispatcher (inject a TestCoroutineDispatcher) and control it's behavior in your test, or have your call to 'scope.launch' return a Job to your test and call await() on it... I don't think there are methods on regular Dispatchers/CoroutineScopes/coroutineContexts that allow you to wait on them until a dispatcher has finished all its scheduled tasks...
u
How would TestCoroutineDispatcher help me? I though it was for controlling time, like delay etc
Also, not returning a job to join on publicly, is that a bug to you? I thought about it previously in unrelated stuff. I chose to have 2 parts to the Syncer, one which provides the scope as you can see, and the ActualSyncer which has the actual suspend function So callers can choose what they want