Coroutines测试异常未通过TestCoroutineDispatcher和TestCoroutineScope都未处理

问题描述 投票:1回答:2

使用此manual测试协程。编写预期会引发异常的测试会崩溃,而不是通过测试。我不知道我在做什么错。

    private val testDispatcher = TestCoroutineDispatcher()

    @Before
    fun setup() {
        // provide the scope explicitly, in this example using a constructor parameter
        Dispatchers.setMain(testDispatcher)
    }

    @After
    fun cleanUp() {
        Dispatchers.resetMain()
        testDispatcher.cleanupTestCoroutines()
    }

    @Test(expected = RuntimeException::class)
    fun testSomeFunctionWithException() = testDispatcher.runBlockingTest {
        someFunctionWithException()
    }


    private fun someFunctionWithException() {
        MainScope().launch {
            throw RuntimeException("Failed via TEST exception")
        }
    }

以上测试方法和以下测试方法

    private val testScope = TestCoroutineScope()
    private lateinit var subject: Subject

    @Before
    fun setup() {
        // provide the scope explicitly, in this example using a constructor parameter
        subject = Subject(testScope)
    }

    @After
    fun cleanUp() {
        testScope.cleanupTestCoroutines()
    }


    @Test(expected = RuntimeException::class)
    fun testFooWithException() = testScope.runBlockingTest {
        subject.fooWithException()
    }

    class Subject(private val scope: CoroutineScope) {


        fun fooWithException() {
            scope.launch {
                println("fooWithException() thread: ${Thread.currentThread().name}")
                throw RuntimeException("Failed via TEST exception")
            }
        }
    }

都崩溃,尽管

注意:当不复杂时,最好提供TestCoroutineScope代码,因为它还会提升异常以测试失败。

  1. 为什么他们两个都崩溃了?
  2. 为什么具有作用域的对象不会失败而不是崩溃?
unit-testing kotlin kotlin-coroutines
2个回答
1
投票

TestCoroutineScope使用TestCoroutineExceptionHandler将处理协程中引发的所有异常,并将它们收集在uncaughtExceptions列表中,尽管第一个异常将在cleanUp或更确切地说是在调用cleanupTestCoroutines()时被抛出,所以您必须对该异常采取措施以防止测试失败。

@After
fun cleanUp() {
    try {
        testScope.cleanupTestCoroutines()
    } catch (e: Exception) {
        //Do something here
    }
}

在测试过程中,您可以检查uncaughtExceptions列表以进行断言:

@Test(expected = RuntimeException::class)
fun testFooWithException() = testScope.runBlockingTest {
    subject.fooWithException()
    assertEquals(1, uncaughtExceptions.size)
    assertEquals(uncaughtExceptions[0].message, "Failed via TEST exception")
}

1
投票

我没有可以轻松测试以下内容的环境,但是请尝试将runBlocking块放入测试函数的主体内。例如:

@Test
fun myTest() {
    runBlocking {
        // Do your test stuff here
    }
}

我发现我以前使用fun myTest() = runBlocking{声明在测试用例中存在问题。似乎测试运行程序无法在体内没有某种断言以及没有返回的情况下检测到测试的执行。像这样。

无论如何,希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.