Тестирование асинхронного кода может быть сложной задачей. Обычно требуется некоторый инструментарий, чтобы заставить его работать с тестовыми фреймворками, такими как junit.
Для проектов Vert.x существует официальный модуль junit , который помогает в написании этих тестов. Тестовый контекст Vertex
в этом модуле сопоставим со стандартным CountDownLatch
. Платформа тестирования ожидает разблокировки защелки и обратный вызов выполняет разблокировку.
К сожалению, это приводит к довольно большому количеству шаблонного кода для простых модульных тестов. К счастью, однако, сопрограммы Kotlin предоставляют чистое решение для написания тестов более традиционным способом.
В этой статье мы рассмотрим, как этого можно достичь, перенеся простой пример на использование сопрограмм Kotlin.
Вот слегка измененная версия первого теста:
@Test @Timeout(value = 5, timeUnit = TimeUnit.SECONDS) void service_is_healthy(Vertx vertx, VertxTestContext testContext) { HttpClient httpClient = vertx.createHttpClient(); httpClient.request(HttpMethod.GET, 8080, "localhost", "/health") .compose(HttpClientRequest::send) .compose(HttpClientResponse::body) .onComplete(testContext.succeeding(buffer -> { JsonObject responseJson = buffer.toJsonObject(); Assertions.assertEquals("up", responseJson.getString("status")); testContext.completeNow(); })); }
Итак, в чем проблемы с этим кодом? Обратите внимание, как тестовый контекст группирует тестовый код. Разве не было бы лучше, если бы нам не приходилось беспокоиться об этом?
Давайте перепишем это с помощью сопрограмм Kotlin:
@Test @Timeout(5, unit = TimeUnit.SECONDS) fun `service is healthy`(vertx: Vertx): Unit = runBlocking(vertx.dispatcher()) { val httpClient = vertx.createHttpClient() val request = httpClient.request(HttpMethod.GET, 8080, "localhost", "/health").await() val response = request.send().await() val responseJson = response.body().await().toJsonObject() Assertions.assertEquals("up", responseJson.getString("status")) }
Как вы можете видеть, мы избавились почти от всего, что не имеет отношения к самому тесту. Это основное преимущество использования сопрограмм для тестов с Vert.x.
Давайте рассмотрим изменения, которые мы здесь внесли. Во-первых, мы завернули тело теста в run Blocking
для того, чтобы иметь возможность запускать сопрограммы внутри теста.
Примечание: Важно, чтобы сопрограммы выполнялись в потоках Vert.x. К счастью, Vert.x предоставляет функцию #dispatcher
, которую мы можем использовать для запустите блокировку
.
Вызовы #await
гарантируют, что исключения приведут к сбою тестов. Они также заставляют junit ждать нашего теста, по сути, делая контекст Vertex Test
устаревшим для наших тестов.
Кроме того, мы избегаем обратных вызовов и вложенности. Это делает наши тесты немного более удобочитаемыми.
Резюме
В этой короткой статье мы увидели, что сопрограммы Kotlin могут значительно снизить уровень шума в асинхронных тестах. Вместо того чтобы бороться с асинхронным характером нашего кода, мы можем сосредоточиться на самих тестах. В следующей части мы увидим, как мы можем добавить несколько помощников, чтобы сделать написание тестов еще проще.
Источник
Полный проект можно найти в этом репозитории GitHub .
Оригинал: “https://dev.to/wowselim/writing-async-tests-for-vert-x-using-kotlin-1ck6”