协程测试失败并显示“此作业尚未完成”

Rob*_*ert 5 unit-testing kotlin kotlin-coroutines

我正在关注 Craig Russell 关于测试协程的博客文章:https : //craigrussell.io/2019/11/unit-testing-coroutine-suspend-functions-using-testcoroutinedispatcher/但我无法通过此测试:

@Test
fun multipleLaunch() = runBlockingTest {
    var result = 0
    val jobs = mutableListOf<Job>()
    for (j in 0 until 10) {
        val job = launch(testDispatcherProvider.io()) {
            delay(1000)
            result++
        }
        jobs.add(job)
    }
    jobs.forEach { job ->
        job.join()
    }
    assertEquals(10, result)
}
Run Code Online (Sandbox Code Playgroud)

基本上,我正在启动一堆并行作业,并希望在所有作业完成后获得结果。我得到了这个,现在经典的例外:

java.lang.IllegalStateException:此作业尚未完成

请告知如何使其按预期工作。

我的完整代码:

class LaunchTest {
    @get:Rule
    var coroutinesTestRule = CoroutineTestRule()

    val testDispatcherProvider = object : DispatcherProvider {
        override fun io(): CoroutineDispatcher = coroutinesTestRule.testDispatcher
    }

    @Test
    fun multipleLaunch() = runBlockingTest {
        var result = 0
        val jobs = mutableListOf<Job>()
        for (j in 0 until 10) {
            val job = launch(testDispatcherProvider.io()) {
                delay(1000)
                result++
            }
            jobs.add(job)
        }
        jobs.forEach { job ->
            job.join()
        }
        assertEquals(10, result)
    }
}

class CoroutineTestRule constructor(val testDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()) : TestWatcher() {
    override fun starting(description: Description?) {
        super.starting(description)
        Dispatchers.setMain(testDispatcher)
    }

    override fun finished(description: Description?) {
        super.finished(description)
        Dispatchers.resetMain()
        testDispatcher.cleanupTestCoroutines()
    }
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*ert 5

解决了。

我完全把这归咎于 Android Studio 的自动完成功能。:)

我只是运行了错误的“runBlockingTest()”。

替换这一行:

fun multipleLaunch() = runBlockingTest {
Run Code Online (Sandbox Code Playgroud)

用这一行:

fun multipleLaunch() = coroutinesTestRule.testDispatcher.runBlockingTest {
Run Code Online (Sandbox Code Playgroud)