【发布时间】:2022-06-11 01:50:45
【问题描述】:
我正在使用 ktor 在 Kotlin 中开发微服务。为了测试一种方法,我需要创建一个虚拟 HttpResponse(具体来说是io.ktor.client.statement.HttpResponse)对象,其状态 = 200 和 body = 一些 json 数据。
知道如何创建它吗?
【问题讨论】:
标签: kotlin httpresponse ktor
我正在使用 ktor 在 Kotlin 中开发微服务。为了测试一种方法,我需要创建一个虚拟 HttpResponse(具体来说是io.ktor.client.statement.HttpResponse)对象,其状态 = 200 和 body = 一些 json 数据。
知道如何创建它吗?
【问题讨论】:
标签: kotlin httpresponse ktor
我通过以下方式做到了这一点。我只需要传递一个状态码和描述,其他字段就不用管了。
class CustomHttpResponse(
private val statusCode: Int,
private val description: String
) :
HttpResponse() {
@InternalAPI
override val content: ByteReadChannel
get() = TODO("Not yet implemented")
override val call: HttpClientCall
get() = TODO("Not yet implemented")
override val coroutineContext: CoroutineContext
get() = TODO("Not yet implemented")
override val headers: Headers
get() = TODO("Not yet implemented")
override val requestTime: GMTDate
get() = TODO("Not yet implemented")
override val responseTime: GMTDate
get() = TODO("Not yet implemented")
override val status: HttpStatusCode
get() = HttpStatusCode(statusCode, description)
override val version: HttpProtocolVersion
get() = TODO("Not yet implemented")
}
【讨论】:
您可以使用mockk 或类似的库来模拟HttpResponse。不幸的是,这很复杂,因为HttpRequest、HttpResponse 和HttpClient 对象与HttpClientCall 紧密耦合。以下是您如何做到这一点的示例:
val call = mockk<HttpClientCall> {
every { client } returns mockk {}
coEvery { receive(io.ktor.util.reflect.typeInfo<String>()) } returns "body"
every { coroutineContext } returns EmptyCoroutineContext
every { attributes } returns Attributes()
every { request } returns object : HttpRequest {
override val call: HttpClientCall = this@mockk
override val attributes: Attributes = Attributes()
override val content: OutgoingContent = object : OutgoingContent.NoContent() {}
override val headers: Headers = Headers.Empty
override val method: HttpMethod = HttpMethod.Get
override val url: Url = Url("/")
}
every { response } returns object : HttpResponse() {
override val call: HttpClientCall = this@mockk
override val content: ByteReadChannel = ByteReadChannel("body")
override val coroutineContext: CoroutineContext = EmptyCoroutineContext
override val headers: Headers = Headers.Empty
override val requestTime: GMTDate = GMTDate.START
override val responseTime: GMTDate = GMTDate.START
override val status: HttpStatusCode = HttpStatusCode.OK
override val version: HttpProtocolVersion = HttpProtocolVersion.HTTP_1_1
}
}
val response = call.response
【讨论】:
no answer found for: HttpClientCall(#1).receive(TypeInfoImpl(type=class kotlin.String, reifiedType=class java.lang.String, kotlinType=kotlin.String), continuation {})。知道为什么会这样吗?
HttpClientCall.receive 方法的存根。如果您遇到这种错误,您需要为未实现的方法或属性提供存根。