Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different testCoroutineDispatcher is used within each block #2703

Closed
SumeraMartin opened this issue Dec 2, 2021 · 0 comments · Fixed by #2719
Closed

Different testCoroutineDispatcher is used within each block #2703

SumeraMartin opened this issue Dec 2, 2021 · 0 comments · Fixed by #2719
Labels
bug 🐛 Issues that report a problem or error in the code. framework 🏗️ Pertains to the core structure and components of the Kotest framework.
Milestone

Comments

@SumeraMartin
Copy link

I'm using 5.0.1 version of kotest.

I have the following class:

class TestTarget {
    suspend fun performLongRunningOperation(): Boolean {
        delay(100)
        return true
    }
}

and I have the following test

@OptIn(ExperimentalKotest::class, ExperimentalStdlibApi::class, ExperimentalCoroutinesApi::class)
class CloudTokenUpdaterTest : BehaviorSpec({
    testCoroutineDispatcher = true
    timeout = 5_000
    isolationMode = IsolationMode.InstancePerLeaf

    // This passes
    Given("Target - 2") {
        When("performLongRunningOperation is called") {
            And("long running operation is finished") {
                Then("result is successful") {
                    val target = TestTarget()
                    val result = async { target.performLongRunningOperation() }
                    delayController.advanceTimeBy(1000)
                    result.await() shouldBe true
                }
            }
        }
    }

    // This fails with timeout
    Given("Target - 2") {
        val target = TestTarget()

        When("doSomething is called") {
            val result = async { target.performLongRunningOperation() }

            And("long running operation is finished") {
                delayController.advanceTimeBy(1000)

                Then("result is successful") {
                    result.await() shouldBe true
                }
            }
        }
    }
}

The first test Target - 1 passes successfully as expected. Bu the second test Target - 2 fails with a timeout. After a while of debugging, I found that each block (Given, When, And, Then) is using different TestCoroutineDispatcher so advanceTimeBy in the And block is advancing a different dispatcher that is used in the When block. This causes the test to be stuck and is finished by timeout.

I'm not sure if such behavior is done by intent, but I wasn't expecting that so I think that this is a bug in the library.

However, thanks for the library works very fine otherwise.

@sksamuel sksamuel added this to the 5.0.2 milestone Dec 3, 2021
@sksamuel sksamuel added bug 🐛 Issues that report a problem or error in the code. framework 🏗️ Pertains to the core structure and components of the Kotest framework. labels Dec 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Issues that report a problem or error in the code. framework 🏗️ Pertains to the core structure and components of the Kotest framework.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants