Как написать тестовый пример Junit для метода postAbs WebClient в Vert.x? - PullRequest
1 голос
/ 09 января 2020

Недавно я разработал несколько статей, из которых мне нужно было выполнять внешние вызовы API. Чтобы оптимизировать код, я переместил код вызывающих API в один общий класс Helper. Я также передаю экземпляр Vertx из класса Verticle в класс Helper. Сейчас я пытаюсь написать тестовый пример Junit для класса Helper, который выглядит следующим образом:

public class ServiceExecutionHelper{

public Promise<String> executeService(String requestURI, JsonObject input, MultiMap headers, Vertx vertx){
        Promise<String> promise = Promise.promise();
        WebClient client = WebClient.create(vertx);
        client.postAbs(requestURI).timeout(60000).putHeaders(headers)
        .sendJsonObject(input, ar -> {
            if (ar.succeeded()) {
                HttpResponse<Buffer> response = ar.result();
                JsonObject serviceRespone = new JsonObject(response.bodyAsString());
                JsonArray responseData = serviceRespone.getJsonArray("response_data");
                if(responseData != null){
                    promise.complete("promise_completed");
                }else{
                    promise.fail("promise_failed");
                }
            }
        }
        return promise;
}
}

Может кто-нибудь подсказать, как мне написать тестовый пример для кода выше?

1 Ответ

1 голос
/ 14 января 2020

Существует миллион способов сделать это в зависимости от того, что именно вам нужно протестировать.

Вот одно из предложений с использованием junit5 и okhttp's MockWebServer . Есть много других возможных альтернатив.

Тест проверяет:

  • что вы отправляете запрос POST, используя полезную нагрузку, содержащуюся во входном параметре.
  • То Ваша реализация может обработать ответ json от веб-сервера.
  • что ваша реализация отправляет веб-серверу ровно один запрос.
  • что ваш код завершает Promise, если ответ сервера содержит ключ "promise_completed"
    @ExtendWith(VertxExtension.class)
    @Slf4j
    public class ServiceExecutionHelperTest {

        private ServiceExecutionHelper sut;

        private MockWebServer mockWebServer;

        @BeforeEach
        public void setUp() {
            sut = new ServiceExecutionHelper();
            mockWebServer = new MockWebServer();
        }

        @Test
        public void testExecuteService(final Vertx vertx, final VertxTestContext testContext) throws InterruptedException {
            // given
            final JsonObject requestPayload = new JsonObject().put("request", new JsonArray("[]"));
            final JsonObject serverResponsePayload = new JsonObject().put("response_data", new JsonArray("[]"));
            mockWebServer.enqueue(new MockResponse()
                                      .setBody(serverResponsePayload.encode())
                                      .setResponseCode(200)
                                      .setHeader("content-type", "application/json"));

            // when
            final Promise<String> stringPromise =
                sut.executeService(
                    mockWebServer.url("/").toString(),
                    requestPayload,
                    MultiMap.caseInsensitiveMultiMap(),
                    vertx);

            // then
            final RecordedRequest recordedRequest = mockWebServer.takeRequest();
            assertEquals("POST", recordedRequest.getMethod());
            assertEquals("[text={\"request\":[]}]", recordedRequest.getBody().toString());
            assertEquals(1, mockWebServer.getRequestCount());
            testContext.assertComplete(stringPromise.future())
                       .map(val -> {
                           assertEquals("promise_completed", val);
                           testContext.completeNow();
                           return val;
                       })
                       .onComplete(onComplete -> {
                           assertTrue(onComplete.succeeded());
                           log.info("done");
                       })
                       .onFailure(onError -> Assertions.fail());

        }
    }

Несколько слов с TDD точки зрения

Прежде чем вы начнете писать тесты (и ваш реальный код, если вы спросите меня), вы должны уточнить свои функциональные и технические требования.

Это должно быть основой для ваших испытаний. И тесты должны стать отправной точкой для реализации вашего кода.

Поэтому я не могу обещать вам, что этот пример является правильным тестом для вашего варианта использования. Он компилируется и запускается. Но его следует проверить и расширить в соответствии с вашими фактическими требованиями.

Относительно охвата теста

Чтобы этот ответ был кратким и кратким, я не написал тест, охватывающий все возможные ветки. Случай, когда сервер отвечает без response_data (т. Е. Ветвь else вашего условия if, где Обещание не выполняется), не проверяется.

Чтобы охватить этот случай, второй тест или использование необходим параметризованный тест.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...