Skip to main content
Redhat Developers  Logo
  • Products

    Platforms

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat AI
      Red Hat AI
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • View All Red Hat Products

    Featured

    • Red Hat build of OpenJDK
    • Red Hat Developer Hub
    • Red Hat JBoss Enterprise Application Platform
    • Red Hat OpenShift Dev Spaces
    • Red Hat OpenShift Local
    • Red Hat Developer Sandbox

      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Secure Development & Architectures

      • Security
      • Secure coding
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • Product Documentation
    • API Catalog
    • Legacy Documentation
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

JUnit 5 support lands in Eclipse Vert.x for testing asynchronous operations

January 23, 2018
Julien Ponge
Related topics:
JavaCI/CDDeveloper ToolsMicroservices

Share:

    JUnit 5 is a rewrite of the famous Java testing framework that brings new interesting features, including:

    • nested tests,
    • the ability to give a human-readable description of tests and test cases,
    • a modular extension mechanism that is more powerful than the JUnit 4 runner mechanism (@RunWith annotation),
    • conditional test execution,
    • parameterized tests, including from sources such as CSV data,
    • the support of Java 8 lambda expressions in the reworked built-in assertions API,
    • support for running tests previously written for JUnit 4.

    Testing asynchronous operations is not straightforward

    Eclipse Vert.x is an increasingly popular toolkit for writing reactive applications on the JVM.

    Testing code with asynchronous operations is more challenging than it seems at first sight. Indeed, let us consider the following (incomplete!) test snippet:

    https://gist.github.com/jponge/aa990083c857160bb12ae9a1f627855b

    This test defines a periodic task every 100ms, and we would like to complete the test when the periodic task callback has been executed 3 times. Because setPeriodic defines an asynchronous operation that is being executed on another thread, the test method returns right after the call to setPeriodic, and the test framework considers the method has having succeeded.

    The solution is to make the test framework runner wait until all asynchronous operations have completed successfully or not.

    Vert.x already provided a module called vertx-unit for testing asynchronous operations. Its strengths are that it is polyglot, so it works for all the JVM languages that Vert.x supports, and it provides a JUnit 4 runner.

    With the advent of JUnit 5 we decided to develop a specific integration for JUnit 5 (vertx-junit5) that works great of course with Java but also with the languages that have seamless interoperability with Java and where using JUnit is popular: Kotlin and Groovy. It is important to note that vertx-unit is not being abandoned, as it remains useful for other JVM languages and for projects using JUnit 4.

    An example is better than a thousand words

    To create a test with JUnit 5 and Vert.x we simply define a class:

    https://gist.github.com/jponge/1b289aeb6b4e82d26cfc10e836b38c19

    Making test classes package-protected is a common idiom of JUnit 5.

    The @ExtendWith annotation allows using the Vert.x extension (more on that in a minute!). In fact, a test can use several extensions, contrarily to the runners in JUnit 4. The @DisplayName annotation is optional, but it gives a human-readable description of what the test is doing. Last but not least, you can use emojis!

    Back to our example of counting ticks, here is how we can write it as a method in SampleVerticleTest:

    https://gist.github.com/jponge/079120cd9cc5a4b4ec07e771b06e8805

    The VertTestContext class provides a context for running Vert.x asynchronous operations, and it is used to define when a test completes or fails. Remember that operations are being executed on other threads than the one of the JUnit runner. The call to completeNow() immediately marks the test as successful.

    The Vert.x extension does 2 important things:

    1. it (optionally) injects instances of Vertx and VertxTestContext when a test method has arguments of these types, and
    2. it ensures that the JUnit test runner waits for the asynchronous operations to complete even when the test method execution exits.

    It is possible to create both Vertx and VertxTestContext instances manually if need be, but they provide sensible defaults for a majority of test cases. It is also important to note that VertxTestContext always waits for the test completion with a timeout so as not to block the tests execution forever. The timeout delay can be customized through an annotation.

    Checkpointing

    Not every asynchronous test execution has a single point of completion: there are many cases where you need to check that several specific lines of code have been executed.

    We provide a checkpoint abstraction. When all created checkpoints have been flagged, then a test succeeds.

    Back to our previous example, we can rewrite it more simply using a checkpoint that must be flagged 3 times:

    https://gist.github.com/jponge/1f19d5d4d810867a87faaad4a436b0ac

    An integration test (+ other goodies)

    The Vert.x functional unit of event-processing code is called a verticle. In short, a verticle processes asynchronous events and it is managed by an event-loop, which is itself permanently tied to a thread.

    Let us consider the following verticle. It starts a HTTP server on port 11981 and answers all requests with the "Yo!" text:

    https://gist.github.com/jponge/2c2303667da58239acfebbcbd49b5e74

    Now let us write an integration test for this verticle. More specifically, we need to ensure that:

    1. The verticle is successfully deployed in a Vertx context, and
    2. We need to issue HTTP requests and check the responses.

    We will do that and also issue 10 HTTP client requests.

    The test fits in the following method:

    https://gist.github.com/jponge/be4b3e65da36fbe4d111b21f49a947a5

    Many asynchronous operations in Vert.x require a AsyncResult<T> callback, where AsyncResult contains either a value in case of success, or an exception in case of failure. To make the test code easier and avoid a "if / else blocks dance", VertxTestContext provides succeeding and failing helper methods.

    Here we use succeeding in 2 places because we expect successes, and we pass a callback that handles the AsyncResult value.

    Another important point is that our JUnit 5 support is agnostic of the test assertion library. You may use the built-in JUnit assertions API, or do like in our example and use AssertJ. All you have to do is call verify with a lambda where assertions can be placed. Any exception thrown from inside the lambda makes the test fail with that exception.

    A complete example

    Here is a complete test example, including JUnit 5 features like life-cycle callbacks and a nested test that shows how to use custom Vertx and VertxTestContext objects:

    https://gist.github.com/jponge/3c04d422f0969da04d0283859fefd5e7

    Going further

    • The Vert.x website provides a comprehensive description of the Vert.x ecosystem.
    • The Vert.x JUnit 5 module provides a complete documentation.
    • The Vert.x examples repository contain the full source code for the examples given in this article, and are generally a great resource to explore "all things Vert.x"!

    Recent Posts

    • A deep dive into Apache Kafka's KRaft protocol

    • Staying ahead of artificial intelligence threats

    • Strengthen privacy and security with encrypted DNS in RHEL

    • How to enable Ansible Lightspeed intelligent assistant

    • Why some agentic AI developers are moving code from Python to Rust

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit
    © 2025 Red Hat

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue