How to inject coroutine dispatcher in Unit Test - using Koin

I am injecting my dispatcher, using Koin, into my classes

Extract of one class using Koin

class LogsWorker(
    val context: Context,
    workerParameters: WorkerParameters
) : CoroutineWorker(context, workerParameters), KoinComponent {


    private val ioDispatcher: CoroutineDispatcher by inject()
}

koinModule:

val appModule = module {
    factory { provideIoDispatcher() }
}

private fun provideIoDispatcher(): CoroutineDispatcher = Dispatchers.IO

If I want to unit test my LogsWorker class, I need to inject a coroutineTestDispatcher. How could I do that? I don't find any example anywhere.

1 answer

  • answered 2021-07-28 07:56 Róbert Nagy

    You need to override that bean definition in your testing, when you are loading you are starting koin and loading the modules.

    You can do that with: factory(override = true) { provideYourTestingDispatcher }

    Read more about it here

    Although the above could work, I just find it more elegant to use constructor injection instead, for ex:

    class LogsWorker(
        val context: Context,
        workerParameters: WorkerParameters,
        private val ioDispatcher: CoroutineDispatcher
    ) : CoroutineWorker(context, workerParameters)
    

    Then you can just specify the definition for LogsWorker in koin, such as:

    factory { (context: Context, workerParameters: WorkerParameters) -> LogsWorker(context, workerParameters, get()) }
    

    And in testing, you can just simply pass in the testing dispatcher. More info about this: https://insert-koin.io/docs/reference/koin-core/injection-parameters#defining-an-injected-parameter

    UPDATE: override is deprecated, you could use KoinApplication.allowOverride(true) instead

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum