使用 Kotlin Channel 进行单元测试

Posted

技术标签:

【中文标题】使用 Kotlin Channel 进行单元测试【英文标题】:Unit test with Kotlin Channel 【发布时间】:2022-01-12 20:36:29 【问题描述】:

我开始学习如何使用 Channel,但在单元测试方面遇到了问题。例如类

class TestOp (private val channel: Channel<String>) 
    suspend fun op() 
        channel.send("new")
    

并进行测试

@ExtendWith(CoroutineExecutorExtension::class)
@RunWith(JUnitPlatform::class)
internal class TestOpTest

    @Test
    fun testOpReturnNew() 
        runBlockingTest 
           val channel = Channel<String>()
           val test = TestOp(channel = channel)
           test.op()
           assertEquals("new", channel.receive())
        
    

地点:

@ExperimentalCoroutinesApi
class CoroutineExecutorExtension : InstantExecutorExtension() 

    private val testCoroutineDispatcher = TestCoroutineDispatcher()

    override fun beforeEach(context: ExtensionContext?) 
        super.beforeEach(context)
        Dispatchers.setMain(testCoroutineDispatcher)
    

    override fun afterEach(context: ExtensionContext?) 
        super.afterEach(context)
        Dispatchers.resetMain()
        testCoroutineDispatcher.cleanupTestCoroutines()
    


@ExperimentalCoroutinesApi
open class InstantExecutorExtension : BeforeEachCallback, AfterEachCallback 

    override fun beforeEach(context: ExtensionContext?) 
        ArchTaskExecutor.getInstance()
            .setDelegate(object : TaskExecutor() 
                override fun executeOnDiskIO(runnable: Runnable) = runnable.run()

                override fun postToMainThread(runnable: Runnable) = runnable.run()

                override fun isMainThread(): Boolean = true
            )
    

    override fun afterEach(context: ExtensionContext?) 
        ArchTaskExecutor.getInstance().setDelegate(null)
    



我得到错误:

此作业尚未完成 java.lang.IllegalStateException:此作业尚未完成 在 kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1190) 在 kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:53) 在 kotlinx.coroutines.test.TestBuildersKt.runBlockingTest$default(TestBuilders.kt:45)​​

如果我使用runBlocking,测试永远不会完成。

什么是正确的测试方法?

【问题讨论】:

我想你把 delay(1000) 放在断言之前。 【参考方案1】:

我修复了添加的问题:

@AfterEach
fun tearDown() 
   viewModel.viewModelScope.cancel()

这样所有的协程都被取消了,问题就解决了

【讨论】:

以上是关于使用 Kotlin Channel 进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Cordapp 中对服务和控制器(kotlin)进行单元测试?

Kotlin 协程Channel 通道 ② ( Channel 通道容量 | Channel 通道迭代 | 使用 iterator 迭代器进行迭代 | 使用 for in 循环进行迭代 )

Kotlin 协程Channel 通道 ② ( Channel 通道容量 | Channel 通道迭代 | 使用 iterator 迭代器进行迭代 | 使用 for in 循环进行迭代 )

在Android上Kotlin的单元测试(KAD22)

Android 仪器化单元测试(instrumented unit tests) Androidx kotlin版本

Gradle 没有找到我使用 Kotlin 和 JUnit 5 进行的测试