当前位置: 首页 > 知识库问答 >
问题:

单元测试挂起coroutine

左丘善
2023-03-14

对Kotlin来说有点新,并测试它...我试图使用suspend方法测试dao对象包装器,该方法对SQL返回对象使用awaitFirst()。然而,当我为它编写单元测试时,它只是停留在一个循环中。我认为这是由于awaitFirst()不在相同的测试范围内

suspend fun queryExecution(querySpec: DatabaseClient.GenericExecuteSpec): OrderDomain {
        var result: Map<String, Any>?
        try {
            result = querySpec.fetch().first().awaitFirst()
        } catch (e: Exception) {
            if (e is DataAccessResourceFailureException)
                throw CommunicationException(
                    "Cannot connect to " + DatabaseConstants.DB_NAME +
                        DatabaseConstants.ORDERS_TABLE + " when executing querySelect",
                    "querySelect",
                    e
                )
            throw InternalException("Encountered R2dbcException when executing SQL querySelect", e)
        }

        if (result == null)
            throw ResourceNotFoundException("Resource not found in Aurora DB")

        try {
            return OrderDomain(result)
        } catch (e: Exception) {
            throw InternalException("Exception when parsing to OrderDomain entity", e)
        } finally {
            logger.info("querySelect;stage=end")
        }
    }
@Test
    fun `get by orderid id, null`() = runBlocking {
        // Assign
        Mockito.`when`(fetchSpecMock.first()).thenReturn(monoMapMock)
        Mockito.`when`(monoMapMock.awaitFirst()).thenReturn(null)

        // Act & Assert
        val exception = assertThrows<ResourceNotFoundException> {
            auroraClientWrapper.queryExecution(
                databaseClient.sql("SELECT * FROM orderTable WHERE orderId=:1").bind("1", "123") orderId
            )
        }
        assertEquals("Resource not found in Aurora DB", exception.message)
    }
private suspend fun queryExecution(querySpec: DatabaseClient.GenericExecuteSpec): Map {
        var result: Map<String, Any>?
        try {
            result = withContext(Dispatchers.Default) {
                querySpec.fetch().first().block()
            }
return result
}

这是否意味着withContext将利用一个新线程,并在其他地方重用旧线程?这并没有真正优化任何东西,因为我仍然会有一个线程被阻塞,而不管产生一个新的上下文?

共有1个答案

翟嘉祥
2023-03-14

找到了解决办法。

monomapmock是来自Mockito的模拟值。似乎kotlinx-test coroutines不能拦截异步返回单声道。所以我强制我可以模拟的方法返回一个真实的单值,而不是模拟的单值。按照路易斯的建议。我停止嘲笑它,返回一个真正的值

@Test
    fun `get by orderid id, null`() = runBlocking {
        // Assign
        Mockito.`when`(fetchSpecMock.first()).thenReturn(Mono.empty())
        Mockito.`when`(monoMapMock.awaitFirst()).thenReturn(null)

        // Act & Assert
        val exception = assertThrows<ResourceNotFoundException> {
            auroraClientWrapper.queryExecution(
                databaseClient.sql("SELECT * FROM orderTable WHERE orderId=:1").bind("1", "123") orderId
            )
        }
        assertEquals("Resource not found in Aurora DB", exception.message)
    }
 类似资料:
  • 我想测试我的Spring应用程序。当我将@SpringBootTest添加到我的测试类中时,即使我等待了一个多小时,测试也会挂起并且不会开始!删除SpringBootTest注释会导致初始化@Value字段失败,并且我无法测试任何组件类。我的配置类代码: 我的测试类: 运行测试类时的堆栈跟踪: 当我运行该测试时,该测试处于挂起状态:

  • Android Studio 1.1 添加了单元测试支持,详细请看 Unit testing support。本章的其余部分描述的是 “instrumentation tests”。利用 Instrumentation 测试框架可以构建独立的测试 APK 并运行在真实设备(或模拟器)中进行测试。

  • 英文原文:http://emberjs.com/guides/testing/unit/ 单元测试用于测试代码的一个小片段,确保其功能正常。与集成测试不同,单元测试被限定在一个范围内,并且不需要Ember应用运行。 全局 vs 模块 过去如果没有作为一个全局变量加载整个Ember应用,要对应用进行测试非常困难。通过使用模块(CommonJS,AMD等)来编写应用,可以只加载被测试的部分,而不用将其

  • 单元测试涉及测试软件应用程序的每个单元或单个组件。这是第一级软件测试。单元测试的目的是验证单元组件的性能。 单元是软件系统的单个可测试部分,并在应用程序软件的开发阶段进行测试。 此测试旨在测试隔离代码的正确性。单元组件是应用程序的单独功能或代码。白盒测试方法用于单元测试,通常由开发人员完成。 在测试级别层次结构中,单元测试是在集成和其他剩余测试级别之前完成的第一级测试。它使用模块进行测试,减少了等

  • 单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如 C 语言中单元指一个函数,Java 里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进

  • 我们从 Hello World 项目入手,增加单元测试功能。 我们新家了一个名为hello-world-test的 Gradle 项目。 环境 Gradle 3.4.1 Spring Boot 1.5.2.RELEASE Thymeleaf 3.0.3.RELEASE Thymeleaf Layout Dialect 2.2.0 Spring Security Test 4.2.2.RELEASE