本文介绍了当协程包含协程延迟时,如何对其进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在视图模型中添加协程delay()时,将不执行代码的其余部分.

When I add a coroutine delay() in my view model, the remaining part of the code will not be executed.

这是我的演示代码:

class SimpleViewModel : ViewModel(), CoroutineScope {

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Unconfined

    var data = 0

    fun doSomething() {
        launch {
            delay(1000)
            data = 1
        }
    }
}

class ScopedViewModelTest {

    @Test
    fun coroutineDelay() {
        // Arrange
        val viewModel = SimpleViewModel()

        // ActTes
        viewModel.doSomething()

        // Assert
        Assert.assertEquals(1, viewModel.data)
    }
}

我得到了断言结果:

java.lang.AssertionError:
Expected :1
Actual   :0

有什么办法解决这个问题吗?

Any idea how to fix this?

推荐答案

您启动一个协程,该协程在将data设置为1之前会暂停1秒钟.您的测试只会调用doSomething,而不会等到data被执行实际被设置.如果您将另一个更长的delay添加到测试中,它将起作用:

You start a coroutine which suspends for 1 second before setting data to 1. Your test just invokes doSomething but does not wait until data is actually being set. If you add another, longer delay, to the test it will, work:

@Test
fun coroutineDelay() = runBlocking {
    ...
    viewModel.doSomething()
    delay(1100)
    ...
}

您还可以使协程返回Deferred,您可以等待:

You can also make the coroutine return a Deferred which you can wait on:

fun doSomething(): Deferred<Unit> {
    return async {
        delay(1000)
        data = 1
    }
}

有了await,就不再需要延迟代码了:

With await there's no need to delay your code anymore:

val model = SimpleViewModel()
model.doSomething().await()

这篇关于当协程包含协程延迟时,如何对其进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-13 23:23