3

I use the Funspec testing style in kotest and I get a coroutineScope injected automatically by the framework as shown below.

class MyTestSpec: FunSpec() {
    init {
        test("test event loop") {
           mySuspendedFunction() // a coroutineScope is already injected by the test framework here     
        }
    }
}

How can I configure the Kotest framework to use an instance of kotlinx.coroutines.test.TestCoroutineScope instead of a kotlinx.coroutines.CoroutineScope in my tests? or is there a reason why this wouldn't make sense?

rogue-one
  • 11,259
  • 7
  • 53
  • 75

2 Answers2

4

Since Kotest 5.0, there is built-in support for TestCoroutineDispatcher. See here

Simply:

class MyTest : FunSpec(
  {
    test("do your thing").config(testCoroutineDispatcher = true) { 
    }
  }
)
sksamuel
  • 16,154
  • 8
  • 60
  • 108
Emil Kantis
  • 1,069
  • 7
  • 17
3

Create a test listener like this:

class MainCoroutineListener(
    val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()

) : TestListener {
    override suspend fun beforeSpec(spec: Spec) {
        Dispatchers.setMain(testDispatcher)
    }

    override suspend fun afterSpec(spec: Spec) {
        Dispatchers.resetMain()
        testDispatcher.cleanupTestCoroutines()
    }
}

Then use it in your test like this

class MyTest : FunSpec({
    listeners(MainCoroutineListener())
    tests...
})
Tord Jon
  • 46
  • 1
  • thanks any reason the dispatcher has to be reset after each spec? can't I leave it as it is as I want all the tests to use TestCoroutineScope instead of the normal one.. – rogue-one Oct 02 '21 at 17:01
  • The listener will run before every spec so you only need to apply the listener once anyways. – Tord Jon Oct 03 '21 at 08:16