Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 模拟HTTP响应_Java_Exception_Mockito_Okhttp - Fatal编程技术网

Java 模拟HTTP响应

Java 模拟HTTP响应,java,exception,mockito,okhttp,Java,Exception,Mockito,Okhttp,我有下面的方法,它执行GET请求3次,直到成功 模仿这种方法的更好方法是什么?我想模拟和测试状态代码401和状态代码500,并想测试该方法是否执行了三次 在python中,我们有直接模拟请求的方法,因此很容易测试这些方法 Java中是否有类似的东西 @Override public <T> UResponse<T> get(Request request, JSONUnmarshaler<T> unmarshaller, Gson gson) thro

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

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

在python中,我们有直接模拟请求的方法,因此很容易测试这些方法

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();

        }
@覆盖
公共UResponse get(请求请求、JSONMarshaler解组器、Gson Gson)抛出UEException{
int status_code=0;
字符串next=null;
字符串rawJSON=null;
JsonElement JsonElement=null;
布尔重试=真;
试一试{
int=3;
而((尝试次数>=0)&&(重试)&&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();
如果(状态\代码==401){
试一试{
logger.warn(“令牌已过期”);
时间单位。秒。睡眠(5);
重试=真;
}捕捉(中断异常e){
e、 printStackTrace();
}
}
如果((状态代码/100)==5){
logger.warn(“网关错误”);
重试=真;
}
尝试次数-=1;
重试=错误;
}
如果(状态代码!=200){
抛出新的UEException();
}
返回新的响应(状态代码、下一步、rawJSON、,
fromJSON(gson,jsonelement.getAsJsonObject());
}捕获(IOE异常){
e、 printStackTrace();
抛出新的UEException();
}

这将很难测试,因为它会循环。一个解决方案是将
This.client.newCall(request).execute()
分解为一个单独的函数
sendRequest(request-request,int-attemptsRemaining)
。然后您可以使用一个stub该方法的间谍根据剩余的尝试次数返回不同的响应。
关于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();

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

可以将模拟框架添加到依赖项列表中,这一切都很好&很好,但是,我比较老式,更喜欢模拟
远程调用
执行
方法:

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

用法:


您可以(使用mockito、jmockit等)模拟
client.newCall(request).execute()
调用以返回预期响应并检查调用次数,或者使用(MIT)更简单的方法,设置您的规则,并检查它是否使用或可能使用@Morfic谢谢,这真的很有帮助。.Np,一旦您的答案生效,请随时发布您的答案,以便其他人也可以从中受益。干杯谢谢。我不知道您也可以将请求传递给响应生成器。我想模拟响应,以便在response.body().byteStream()。我该怎么做?
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\"}");