Skip to content

Instantly share code, notes, and snippets.

@kingargyle
Created July 31, 2020 19:27
Show Gist options
  • Save kingargyle/c6b0b8db9c010fc7ceebbb74e5bc0952 to your computer and use it in GitHub Desktop.
Save kingargyle/c6b0b8db9c010fc7ceebbb74e5bc0952 to your computer and use it in GitHub Desktop.
A JUnit 4 test rule for working with testing coroutines.
package com.abercrombie.testing.ui.rules
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.TestCoroutineScope
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.test.setMain
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
/**
* Rule to add a simple way to set a test main dispatcher and a custom test scope and reseting
* them to their defaults after the evaluation is done:
*
* https://proandroiddev.com/how-to-unit-test-code-with-coroutines-50c1640f6bef
* https://github.com/Kotlin/kotlinx.coroutines/tree/master/kotlinx-coroutines-test
*/
@ExperimentalCoroutinesApi
class CoroutinesRule(
private val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher(),
private val testCoroutineScope: TestCoroutineScope = TestCoroutineScope(testDispatcher)
) : TestRule {
override fun apply(base: Statement, description: Description?) = CoroutinesStatement(base)
fun runBlockingTest(block: suspend TestCoroutineScope.() -> Unit) {
testCoroutineScope.runBlockingTest { block() }
}
inner class CoroutinesStatement(private val base: Statement) : Statement() {
override fun evaluate() {
Dispatchers.setMain(testDispatcher)
base.evaluate()
Dispatchers.resetMain()
testCoroutineScope.cleanupTestCoroutines()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment