嘲笑 okhttp 响应



我有以下方法,它执行 GET 请求 3 次,直到成功。

嘲笑这种方法的更好方法是什么?我想模拟和测试 status_code 401,状态代码 500,并想测试该方法是否执行了三次。

在python中,我们有 https://github.com/getsentry/responses 直接模拟请求,因此测试这些方法很容易。

Java中有什么等效的吗?

@Override
    public <T> UResponse<T> get(Request request, JSONUnmarshaler<T> unmarshaller, Gson gson) throws UException {
        int status_code = 0;
        String next = null;
        String rawJSON = null;
        JsonElement jsonelement = null;
        Boolean retry = true;
        try {
            int attempts = 3;
            while ((attempts >= 0)  && (retry) && status_code != 200){
                Response response = this.client.newCall(request).execute();
                rawJSON = response.body().string();
                jsonelement = gson.fromJson(rawJSON, JsonElement.class);
                next = gson.fromJson(jsonelement.getAsJsonObject().get("next"), String.class);
                status_code = response.code();
                if (status_code == 401) {
                    try {
                        logger.warn("token expired");
                        TimeUnit.SECONDS.sleep(5);
                        retry = true;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if ((status_code / 100 ) == 5){
                    logger.warn("gateway error");
                    retry = true;                   
                }
                attempts -= 1;
                retry = false;
            }
            if (status_code != 200){
                throw new UException();
            }
            return new UResponse<T>(status_code, next, rawJSON,
                    unmarshaller.fromJSON(gson, jsonelement.getAsJsonObject()));
        } catch (IOException e) {
            e.printStackTrace();
            throw new UException();
        }

这将很难测试,因为它是循环的。一种解决方案是将this.client.newCall(request).execute()分解为一个单独的函数sendRequest(Request request, int attemptsRemaining)。然后,您可以使用存根该方法的间谍根据剩余的尝试次数返回不同的响应。
我意识到okhttp的好处是你可以自己建立一个虚假的响应。例如

Request mockRequest = new Request.Builder()
                .url("https://some-url.com")
                .build();
return new Response.Builder()
                .request(mockRequest)
                .protocol(Protocol.HTTP_2)
                .code(401) // status code
                .message("")
                .body(ResponseBody.create(
                        MediaType.get("application/json; charset=utf-8"),
                        "{}"
                ))
                .build();

因此,您可以创建并存根一个返回响应的简单方法,并且基本上可以进行测试。

你可以将模拟框架添加到你的依赖项列表中,这一切都很好,但是,我是老式的,更喜欢嘲笑remoteCallexecute方法:

将此方法复制到测试类中:

private static OkHttpClient mockHttpClient(final String serializedBody) throws IOException {
        final OkHttpClient okHttpClient = mock(OkHttpClient.class);
        final Call remoteCall = mock(Call.class);
        final Response response = new Response.Builder()
                .request(new Request.Builder().url("http://url.com").build())
                .protocol(Protocol.HTTP_1_1)
                .code(200).message("").body(
                   ResponseBody.create(
                        MediaType.parse("application/json"),
                        serializedBody
                ))
                .build();
        when(remoteCall.execute()).thenReturn(response);
        when(okHttpClient.newCall(any())).thenReturn(remoteCall);
        return okHttpClient;
    }

用法:

final OkHttpClient mockedClient = mockHttpClient("{"key": "val"}");
@Test
fun verifyFailureSingleEventListener() = runBlocking {
    val sender = createSender(webServer.url("/").toString())
    webServer.enqueue(MockResponse().setResponseCode(400))
    val testEvent1 = mutableMapOf("Click" to "Open")
    sender.sendSingleEvent(testEvent1)
    assertEquals("Failure", eventListener.getStatus())
    eventListener.resetStatus()
}

我们可以将模拟响应设置为具有 400 状态代码或其他状态代码来模拟响应

相关内容

  • 没有找到相关文章

最新更新