【问题标题】:How to unit test function that has coroutine `GlobalScope.launch`如何对具有协程`GlobalScope.launch`的函数进行单元测试
【发布时间】:2019-08-14 07:05:22
【问题描述】:

我有这个功能

    override fun trackEvent(trackingData: TrackingData) {
        trackingData.eventsList()
    }

我可以进行如下测试。

    @Test
    fun `My Test`() {
        // When
        myObject.trackEvent(myTrackingMock)

        // Then
        verify(myTrackingMock, times(1)).eventsList()
    }

但是,如果我把它变成一个

    override fun trackEvent(trackingData: TrackingData) {
        GlobalScope.launch{
            trackingData.eventsList()
        }
    }

我怎样才能让我的测试继续运行? (即可以使launch同步吗?)

【问题讨论】:

    标签: unit-testing kotlin kotlin-coroutines


    【解决方案1】:

    要接近答案,请尝试提出一个相关问题:“我如何对具有

    的函数进行单元测试
    Thread { trackingData.eventsList() }
    

    在里面吗?”

    您唯一的希望是运行一个循环,在一段时间内反复检查预期条件,直到放弃并宣布测试失败。

    当您写 GlobalScope.launch 时,您放弃了对 Kotlin 结构化并发的兴趣,因此您将不得不求助于非结构化和非确定性的测试方法。

    另一方面,也许您实际上并不想使用GlobalScope,只是不知道更好吗?在这种情况下,重写您的代码以使用您控制的范围。

    【讨论】:

    • 感谢@MarkoTopolnik。我已经这样做了,它现在按照我的以下答案工作
    【解决方案2】:

    我创建了自己的CoroutineScope 并传入(例如CoroutineScope(Dispatchers.IO) 作为变量myScope

    然后有我的功能

        override fun trackEvent(trackingData: TrackingData) {
            myScope.launch{
                trackingData.eventsList()
            }
        }
    

    然后在我的测试中,我通过创建一个blockCoroutineScope 来模拟范围,如下所示。

       class BlockCoroutineDispatcher : CoroutineDispatcher() {
            override fun dispatch(context: CoroutineContext, block: Runnable) {
                block.run()
            }
        }
    
        private val blockCoroutineScope = CoroutineScope(BlockCoroutineDispatcher())
    

    对于我的测试,我会将blockCoroutineScope 传递为myScope。然后以launch作为阻塞操作执行测试。

    【讨论】:

    • 如果您遵循 Kotlin 人的建议并将 trackEvent 扩展为 CoroutineScope: fun CoroutineScope.trackEvent(...),您可以改进这一点。例如,launch 块有一个CoroutineScope 作为它的接收者,所以如果你在其中调用trackEvent,你会自动将该范围传递给它。对于单元测试,用runBlocking 包围它,它也有CoroutineScope 作为接收器。
    猜你喜欢
    • 1970-01-01
    • 2019-04-15
    • 2018-09-16
    • 2018-04-20
    • 2018-06-15
    • 1970-01-01
    • 2014-02-08
    • 2020-05-07
    • 2019-04-15
    相关资源
    最近更新 更多