我有以下方法,该方法执行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();
}
答案 0 :(得分:5)
可以将一些模拟框架添加到依赖项列表中,这一切都很好,但我是老式的,只喜欢模拟remoteCall
和execute
方法:>
将此方法复制到您的测试类中:
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\"}");
答案 1 :(得分:1)
这很难测试,因为它会循环。一种解决方案是将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();
因此,您可以创建并添加一个简单的方法来返回响应,并且基本上可以进行测试了。
答案 2 :(得分:0)
@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()
}
我们可以设置 mockresponse 有 400 状态码或其他状态码来模拟响应