kotlin - 在挂起函数中异步调用 ktor http 客户端
问题描述
我有以下使用 ktor 的 HttpClient 的函数。tokenService getAccessToken 函数也使用 ktor 客户端并获取令牌。
suspend fun addUser(user: User): User {
return client.post("${Base}api/v1/adduser") {
contentType(ContentType.Application.Json)
header("Authorization", "Bearer ${tokenService.getAccessToken()}")
body = user
}
}
这是我的简单测试
@Test
fun `should add user`() = runBlocking {
delay(3000)
val user = userService.addUser(User("john doe"))
user.firstName shouldBe "john doe"
}
现在测试由于延迟而通过,延迟为首先获取令牌提供了时间,但是如果我删除延迟,则调用 addUser 函数而不先获取令牌。我的问题是,有没有更好的方法来做到这一点,以避免增加测试延迟。我查看了 Kotlin Flows,但我不知道如何为我的场景实现它。如果你能指出我正确的方向,我将不胜感激。
解决方案
这是一般单元测试的常见问题。想想当你必须向数据库发出请求时,我们不想启动整个数据库来进行单元测试,这会使测试变得缓慢和繁琐。我们希望从我们的单元测试中获得快速反馈,而不是到处添加延迟。
一种常见的方法是使用模拟库Mockito
或Mockk
模拟网络服务(在您的情况下tokenService
)。如果您使用Mockito
参考,您可以执行以下操作:
val mockTokenService = Mockito.mock(TokenService::class.java)
Mockito.`when`(mockTokenService.getAccessToken()).thenReturn("sampleToken123")
这样你就可以delay(3000)
从你的单元测试中删除。然后,如果测试通过,您将知道您的addUser
方法业务逻辑将是正确的,并且您可以单独测试令牌服务,如果您愿意,可以使用更多涉及的集成测试或其他模拟。
推荐阅读
- php - laravel - 如何在控制器中实现 Heartland 支付方式
- python - python从字典词典中制作平均值列表:所有平均值相同
- c# - 如何在 C# 的轮播视图中显示下一张图片?
- regex - 如何在python中使用正则表达式从文本中删除项目符号
- spring-boot - SpringBoot中的单元测试Freemarker模板 - 无法初始化freemarker配置
- string - 错误类型“字符串”不是类型转换颤振 sqflite 中“num”类型的子类型
- c# - 将数据从 UserControl 传递到窗体
- html - 使用 CSS 定位元素
- c - C LANG 使用数组读取列和行
- typescript - LoopBack 4:向 SOAP 请求中的元素添加类型属性