6

我正在使用燃料库在 kotlin 中发出一些 http 请求。我想使用 mockk 库测试该代码。我想出了如何模拟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)

我在这里想念什么?

4

3 回答 3

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”扩展功能。我只能让模拟响应最后一个被模拟的项目,而不是正确的项目,但 YMMV ......

于 2020-06-18T15:11:08.027 回答
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") 

顺便说一句,此代码未经过全面测试。使用风险自负

于 2019-11-01T00:12:36.307 回答
0

尝试使用以下内容:

 every { client.executeRequest(req) } returns <mock object>
于 2018-11-15T12:08:48.830 回答