junit 带有主调度程序的模块初始化失败,对于测试调度程序,可以使用kotlinx-coroutines-test模块中的setMain

wwtsj6pe  于 2023-04-30  发布在  Kotlin
关注(0)|答案(1)|浏览(212)

我正在尝试为包含异步调用的方法编写测试。

fun openIntercom(intercomId: String, onCompletable: (Boolean) -> Unit) {
    CoroutineScope(Dispatchers.IO).launch {
        try {
            apiRepository.openIntercomByJWT(intercomId.toInt()).apply {
                if (this != null && this.status.equals("ok")) {
                    withContext(Dispatchers.Main) { onCompletable(true) }
                } else {
                    withContext(Dispatchers.Main) { onCompletable(false) }
                }
            }
        } catch (e: Exception) {
            Timber.e(e, "[openIntercom] error")
            withContext(Dispatchers.Main) { onCompletable(false) }
        }
    }
}

测试:

@Test
fun `openIntercom and return success`() = runTest{
    val viewModel = IntercomMainViewModel(apiRepository)

    coEvery { apiRepository.openIntercomByJWT(any()) } returns StatusResponseData("ok")

    var result = false
    viewModel.openIntercom("123") { b ->
        result = b
    }

    Assert.assertEquals(true, result)
}

但我得到一个错误:java.lang.IllegalStateException:具有主调度程序的模块初始化失败。对于测试调度程序。可以使用kotlinx-coroutines-test模块中的setMain。
如果我删除runTest{},那么我会得到一个错误:io.mockk.MockKException:未找到答案:ApiRepository(#1)。openIntercomByJWT(123,continuation {})
我做错了什么?
我补充道:

class TestViewModelScopeRule(
private val testDispatcher: TestDispatcher = UnconfinedTestDispatcher()) :TestWatcher() {
override fun starting(description: Description?) {
    super.starting(description)
    Dispatchers.setMain(testDispatcher)
}

override fun finished(description: Description?) {
    super.finished(description)
    Dispatchers.resetMain()
}}

testOptions {
    unitTests.returnDefaultValues = true
}
vh0rcniy

vh0rcniy1#

试试加

@BeforeEach
    fun setUp() {
        Dispatchers.setMain(UnconfinedTestDispatcher())
    }

    @AfterEach
    fun tearDown() {
        Dispatchers.resetMain()
    }

使用kotlinx.coroutines.test软件包中的setMain()resetMain()添加到您的测试类。

相关问题