Hello everyone, This is about shortening unit-tes...
# coroutines
s
Hello everyone, This is about shortening unit-tests that use coroutines with delays. In our JVM Kotlin (Android) project we wrote a bunch of unit-tests that execute code containing coroutines that contain delays. With the available standard coroutine-contexts,
delay
calls in the code under test necessitate the need for our tests to call
runBlocking
to get the proper test-results/assertions. This can cause the running of unit test-suites to take a long time. I thought I would write my own
CoroutineContext
implementation to be able to write non-blocking unit test, much like the
TestScheduler
does for testing Rx Java. I managed to write a simple
CoroutineContext
called
TestCoroutineContext
which I based upon the already available
HandlerContext
. But instead of an android
Handler
, I wrote my own proprietary ‘handler’ (one that takes `Runnable`s to be executed asap, later or to be canceled). In addition, I added methods called
advanceTimeBy
,
advanceTimeTo
and
triggerActions
to this
TestCoroutineContext
to simulate the passing of time. E.g. now I can do this kind of unit-test (use
launch
instead of
runBlocking
) Before
Copy code
@ Test
    fun configureMeshNetwork() {
        // This test will take about 3 seconds
        val delay = 3000L
        runBlocking {
            // launchWithDelay runs a coroutine with a `delay`.
            presenter.launchSignInWithDelay(delay)
        }
        verify(mockView).launchSignInActivity()
    }
After, using a `TestCoroutineContext`:
Copy code
@ Test
    fun configureMeshNetwork() {
        // This test will take a few milliseconds
        val delay = 3000L
        launch(testCoroutineContext) {
            // launchWithDelay runs a coroutine with a `delay`.
            presenter.launchSignInWithDelay(delay)
        }

        testCoroutineContext.advanceTimeBy(delay)

        verify(mockView).launchSignInActivity()
    }
My questions are: - Is using the
kotlinx.coroutines.experimental.android.HandlerContext
class as a template for my
TestCoroutineContext
good enough or would my subclass need to implement more of its superclasses’ methods? - Currently, the functions such as
launch
or
async
take a CoroutineContext as an input parameter which is defaulted to a fixed value. Would it be possible to have these functions use a provider/hook so that unit-tests can provide their own contexts to these functions if needed?