У меня есть метод ниже, который выполняет запрос GET 3 раза, пока он не будет успешно выполнен.
Что было бы лучшим способом издеваться над этим методом? Я хочу смоделировать и протестировать код состояния 401, код состояния 500 и проверить, выполняется ли метод трижды.
В python у нас есть https://github.com/getsentry/ответы, который напрямую имитирует запросы, поэтому эти методы легко протестировать.
Есть ли что-нибудь эквивалентное в 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();
}
Или потенциально используйте мок-сервер
@Morfic спасибо, это было действительно полезно ..
Np, не стесняйтесь опубликовать свой ответ, как только он заработает, чтобы другие тоже могли извлечь из этого пользу. Ваше здоровье




Это было бы трудно проверить, потому что это зацикливается. Одним из решений было бы выделить 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();
Таким образом, вы можете создать и заглушить простой метод, который возвращает ответ, и вы в принципе готовы к тестированию.
Спасибо за это. Я не знал, что вы также можете передать запрос в Response Builder.
Я хочу издеваться над ответом, чтобы генерировать исключение при вызове response.body().byteStream(). Как мне это сделать?
Существуют имитирующие фреймворки, которые вы можете добавить в свой список зависимостей, и это все прекрасно и модно, но я старомоден и предпочитаю просто издеваться над методами remoteCall и execute:
copy this method into your test class:
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;
}
usage:
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()
}
мы можем установить mockresponse, чтобы иметь код состояния 400 или другой код состояния для имитации ответа
Вы можете имитировать (с mockito, jmockit и т. д.) вызовы
client.newCall(request).execute(), чтобы вернуть ожидаемый ответ и проверить количество вызовов, или, может быть, более простой способ, использовать okhttp-клиент-макет (MIT), настроить свое правило для 3 раза и проверить, что оно было потребляется