我正在用燃料库在Kotlin中发出一些http请求。我想使用模拟库测试该代码。我想出了如何模拟http请求。下面是该代码。
val client = mockk<Client>()
every { client.executeRequest(any()).statusCode } returns 200
every { client.executeRequest(any()).responseMessage } returns "test"
every { client.executeRequest(any()).data } returns "abc".toByteArray()
FuelManager.instance.client = client
assertEquals("abc" , testHttpRequest())
我不喜欢这里的any()
。我想具体介绍http方法和url。我想基于被调用的url和所使用的http方法返回特定的响应。
我认为我可以做到
val req = Request(Method.POST, "my/test", URL("https://testRequest.com"), timeoutInMillisecond = 3000, timeoutReadInMillisecond = 3000)
every { client.executeRequest(req).statusCode } returns 200
every { client.executeRequest(req).responseMessage } returns "OK"
every { client.executeRequest(req).data } returns "abc".toByteArray()
FuelManager.instance.client = client
但是我遇到以下错误。
io.mockk.MockKException: no answer found for: Client(#1).executeRequest(-->
https://testRequest.com/my/test
"Body : abc"
"Headers : (3)"
Accept-Encoding : compress;q=0.5, gzip;q=1.0
Content-Type : application/json
Authorization : Basic xxx)
我在这里想念什么?
答案 0 :(得分:1)
对于所有最终在此寻求解决方案的人,我发现了可以解决我的用例问题的东西(但是可能有很多用例都不适合我,我接受它可能不是最好的...)。
只要您每次都能始终以相同的顺序呼叫不同端点-
every { client.executeRequest(any()).data} returnsMany listOf(responseBody1, responseBody2, ... , responseBodyN)
对于随后的每个对Fuel客户端的调用,哪个都会返回下一个响应正文。
完整的代码看起来像(使用OP的示例)-
val response1 = "This is response one"
val response2 = "This is response two"
val client = mockk<Client>()
every { client.executeRequest(any()).statusCode } returns 200
every { client.executeRequest(any()).responseMessage } returns "test"
every { client.executeRequest(any()).data } returnsMany listOf(response1.toByteArray(), response2.toByteArray())
FuelManager.instance.client = client
assertEquals("This is response one", testHttpRequest())
assertEquals("This is response two", testHttpRequest())
我怀疑正确的方法是使用MockKMatcherScope
上的'CustomMatcher'扩展功能,详细说明here。我只能让模拟对象对执行此操作时最后被模拟的项目做出回应,而不是正确的项目,而是YMMV ...
答案 1 :(得分:0)
尝试使用以下内容:
every { client.executeRequest(req) } returns <mock object>
答案 2 :(得分:0)
您可以尝试以下行。关于如何拦截加油请求。
fun interceptFuel(method: Method, url: String) {
val interceptor = { next: (Request) -> Request ->
{ req: Request ->
if (req.method == method && req.url.toString() == url) {
val client = mockk<Client>()
/*mock fuel into whatever you like*/
FuelManager.instance.client = client
}
next(req)
}
}
FuelManager.instance.addRequestInterceptor(interceptor)
}
然后,像这样使用它
interceptFuel(Method.GET, "https://google.com")
顺便说一句,此代码尚未完全测试。使用后果自负