Java 模拟HTTP响应
我有下面的方法,它执行GET请求3次,直到成功 模仿这种方法的更好方法是什么?我想模拟和测试状态代码401和状态代码500,并想测试该方法是否执行了三次 在python中,我们有直接模拟请求的方法,因此很容易测试这些方法 Java中是否有类似的东西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
@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,一旦您的答案生效,请随时发布您的答案,以便其他人也可以从中受益。干杯谢谢。我不知道您也可以将请求传递给响应生成器。我想模拟响应,以便在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\"}");