TestCoroutineRule

@ExperimentalCoroutinesApi
class TestCoroutineRule(factory: () -> TestProvidedCoroutineScope) : TestWatcher, TestProvidedCoroutineScope

A basic JUnit 4 TestRule which creates a new TestProvidedCoroutineScope for each test, sets Dispatchers.Main, and calls cleanupTestCoroutines afterwards.

The rule itself implements TestProvidedCoroutineScope, so it can be used as follows:

Before the test:

  • Dispatchers.Main is set to the TestCoroutineDispatcher used by the CoroutineContext.

After the test:

  • cleanupTestCoroutines is called to ensure there are no leaking coroutines. Any unfinished coroutine will throw an UncompletedCoroutinesError.

  • Dispatchers.Main is reset via Dispatchers.resetMain.

Requires JUnit 4.

dependencies {
testImplementation("junit:junit:4.12")
-- or --
testImplementation("org.junit.vintage:junit-vintage-engine:5.5.1")
}

Samples

import dispatch.test.TestCoroutineRule
import dispatch.test.TestProvidedCoroutineScope
import io.kotest.matchers.types.shouldBeInstanceOf
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.Rule
import org.junit.Test
fun main() { 
   //sampleStart 
   @ExperimentalCoroutinesApi
class TestCoroutineRuleSample {

  @JvmField
  @Rule
  val rule = TestCoroutineRule()

  @Test
  fun `rule should be a TestProvidedCoroutineScope`() = runBlocking {

    rule.shouldBeInstanceOf<TestProvidedCoroutineScope>()

    rule.launch {
      // use the rule like any other CoroutineScope
    }
      .join()
  }
} 
   //sampleEnd
}
import dispatch.test.TestCoroutineRule
import dispatch.test.TestProvidedCoroutineScope
import io.kotest.matchers.shouldBe
import io.kotest.matchers.types.shouldBeInstanceOf
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.Rule
import org.junit.jupiter.api.Test
fun main() { 
   //sampleStart 
   @ExperimentalCoroutinesApi
class TestCoroutineRuleWithFactorySample {

  val customScope = TestProvidedCoroutineScope(
    context = CoroutineName("custom name")
  )

  @JvmField
  @Rule
  val rule = TestCoroutineRule { customScope }

  @Test
  fun `rule should be a TestProvidedCoroutineScope`() = runBlocking {

    rule.shouldBeInstanceOf<TestProvidedCoroutineScope>()

    rule.launch {
      // use the rule like any other CoroutineScope
    }
      .join()
  }

  @Test
  fun `rule should be the provided custom scope`() = runBlocking {

    val context = rule.coroutineContext

    context shouldBe customScope.coroutineContext
  }
} 
   //sampleEnd
}

See also

org.junit.rules.TestRule
kotlinx.coroutines.test.TestCoroutineScope

Parameters

factory

optional factory for a custom TestProvidedCoroutineScope. If a factory is not provided, the resultant scope uses the same TestCoroutineDispatcher for each property in its TestDispatcherProvider

Constructors

Link copied to clipboard
fun TestCoroutineRule(factory: () -> TestProvidedCoroutineScope = { TestProvidedCoroutineScope() })

Functions

Link copied to clipboard
open override fun advanceTimeBy(delayTimeMillis: Long): Long
Link copied to clipboard
open override fun advanceUntilIdle(): Long
Link copied to clipboard
open override fun apply(p0: Statement, p1: Description): Statement
Link copied to clipboard
open override fun cleanupTestCoroutines()
Link copied to clipboard
open fun failed(p0: Throwable, p1: Description)
Link copied to clipboard
open override fun pauseDispatcher()
open suspend override fun pauseDispatcher(block: suspend () -> Unit)
Link copied to clipboard
open override fun resumeDispatcher()
Link copied to clipboard
open override fun runCurrent()
Link copied to clipboard
open fun skipped(p0: AssumptionViolatedException, p1: Description)
open fun skipped(p0: AssumptionViolatedException, p1: Description)
Link copied to clipboard
open fun succeeded(p0: Description)

Properties

Link copied to clipboard
open override val coroutineContext: CoroutineContext
Link copied to clipboard
open override val currentTime: Long
Link copied to clipboard
val dispatcher: TestCoroutineDispatcher

The underlying TestCoroutineDispatcher which is responsible for virtual time control.

Link copied to clipboard
open override val dispatcherProvider: DispatcherProvider
Link copied to clipboard
open override val uncaughtExceptions: List<Throwable>

Sources

Link copied to clipboard