Logo

dev-resources.site

for different kinds of informations.

Writing Async Tests for Vert.x using Kotlin

Published at
5/4/2021
Categories
vertx
kotlin
java
testing
Author
wowselim
Categories
4 categories in total
vertx
open
kotlin
open
java
open
testing
open
Author
8 person written this
wowselim
open
Writing Async Tests for Vert.x using Kotlin

Testing asynchronous code can be a challenging task. Usually some tooling is required to make it work with testing frameworks like junit.

For Vert.x projects, there's an official junit module to help writing these tests.
The VertxTestContext in that module is comparable to a standard CountdownLatch. The testing framework waits for the latch to unlock and a callback does the unlocking.

Unfortunately this leads to a quite a bit of boilerplate code for simple unit tests. Luckily though, Kotlin's coroutines provide a clean solution to write tests in a more traditional-looking way.

In this article, we're going to explore how this can be achieved by migrating a simple example to use Kotlin's coroutines.

Here's a slightly modified version of the first test:

@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();
    }));
}
Enter fullscreen mode Exit fullscreen mode

Now, what are the problems with this code? Notice how the the test context clutters the test code. Wouldn't it be nicer if we didn't have to worry about it?

Let's rewrite this using Kotlin coroutines:

@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"))
}
Enter fullscreen mode Exit fullscreen mode

As you can see, we got rid of almost everything that's unrelated to the actual test. This is the main benefit of using coroutines for tests with Vert.x.

Let's go over the changes that we introduced here. First, we wrapped the test body in runBlocking in order to be able to start coroutines inside the test.

Note: It's important that the coroutines run on the Vert.x threads. Luckily, Vert.x provides a #dispatcher function that we can use for runBlocking.

The #await calls make sure that exceptions make the tests fail. They also force junit to wait for our test, esentially making the VertxTestContext obsolete for our tests.

On top of that, we avoid callbacks and nesting. This makes our tests a little more readable.

Summary

In this short article, we saw that Kotlin's coroutines can vastly reduce the noise in asynchronous tests. Instead of fighting with the asynchronous nature of our code, we can focus on the tests themselves. In the next part, we will see how we can add some helpers to make writing tests even easier.

Source

A full project can be found in this GitHub repo.

vertx Article's
28 articles in total
Favicon
Error handlers and failure handlers in Vert.x
Favicon
Why we discarded Reactive systems architecture from our code?
Favicon
Build web application in Vert.x [Part 1/ ♾️]
Favicon
Yet another ode to Vert.x, or how to write a performance-wise expiring map in less than 100 lines of code.
Favicon
Surprising Qualities of Event Driven System
Favicon
Idiomatic Kotlin Abstractions for the Vert.x EventBus
Favicon
Vert.x Circuit Breaker
Favicon
Writing Async Tests for Vert.x using Kotlin
Favicon
Reducing Boilerplate in Vert.x Tests written in Kotlin
Favicon
Writing Vert.x Integration Tests with Kotlin & Testcontainers
Favicon
Quarkus: Entendendo a relação entre o Mutiny e o Vert.x
Favicon
HTTPS Client Certificate Authentication With Java
Favicon
Throttle HTTP requests on paged resources with Vert.x
Favicon
Supercharge Your Kotlin Vert.x Application with EventBus Extensions
Favicon
Handle backpressure between Kafka and a database with Vert.x
Favicon
Handling unknown JSON structures
Favicon
Introduction to Vert.x
Favicon
Future Composition in Vert.x
Favicon
How to extend Vert.x EventBus API to save on serialization.
Favicon
How to write beautiful unit tests in Vert.x
Favicon
Scaling Vert.x application for session dependent data processing.
Favicon
KVision v3.7.0 is released (with Vert.x support)
Favicon
Reactive Java using the Vert.x toolkit
Favicon
Vert.x Kotlin Coroutines
Favicon
How we built a RESTful API with Vert.x, Kotlin Coroutines and Keycloak
Favicon
vertx-jooq 2.4 released
Favicon
Sirix - Released 0.9.1 (time travel queries and versioning made easy)
Favicon
Reactive Programming with Kotlin - Quick Intro to Vert.x

Featured ones: