Kotlin 在挂起函数中异步调用ktor http客户端

Kotlin 在挂起函数中异步调用ktor http客户端,kotlin,ktor,ktor-client,Kotlin,Ktor,Ktor Client,我有以下使用ktor的HttpClient的函数。tokenService getAccessToken函数还使用ktor客户端并获取令牌 suspend fun addUser(user: User): User { return client.post("${Base}api/v1/adduser") { contentType(ContentType.Application.Json) header("Authoriza

我有以下使用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流,但不知道如何在我的场景中实现它。
如果您能为我指出正确的方向,我将不胜感激。

这是单元测试的一个常见问题。想象一下这样一个场景:当您必须向数据库发出请求时,我们不希望为了单元测试而启动整个数据库,这会使测试变得缓慢而繁琐。我们希望从单元测试中得到快速反馈,而不是到处增加延迟

一种常见的方法是使用模拟库,如
Mockito
Mockk
来模拟网络服务(在您的例子中是
tokenService
)。如果使用
Mockito
可以执行以下操作:

val mockTokenService = Mockito.mock(TokenService::class.java)
Mockito.`when`(mockTokenService.getAccessToken()).thenReturn("sampleToken123")

这样您就可以从单元测试中删除
delay(3000)
。然后,如果测试通过,您将知道您的
addUser
方法的业务逻辑将是正确的,并且您可以单独测试令牌服务,如果您愿意,可以使用更复杂的集成测试或其他模拟测试。

这很奇怪,因为如果我使用您的代码并设置延迟(用于测试目的)到
tokenService.getAccessToken()
方法,然后
addUser
始终等待其完成。什么
tokenService.getAccessToken()
会在测试中毫不延迟地返回?因为tokenServcie.getAccessToken()是一个网络调用,它需要几秒钟的时间。当您尝试它时,如果您只是返回一些测试文本,这将足够快,所以不会有任何问题。当我运行代码时,addUser在没有令牌头的情况下被调用,并抛出错误。这就是为什么我试图设置足够大的延迟来模拟网络调用。下面是与预期类似的代码。