Integration Testing using MicroProfile Testing and Payara Micro

Photo of Rudy De Busscher by Rudy De Busscher

 

Integration testing is perceived as difficult, time-consuming and requiring complex setup of 3rd party systems. There are different types of integration testing, such as system, acceptance and release testing, but all types of testing share the need to integrate several units of your application or other systems in your test.

With the help of Eclipse MicroProfile Testing, also known as MicroShed Testing, these things become easier to implement. With the help of TestContainers, MicroProfile Testing makes setting up your application painless and ensures REST endpoints of your application are tested smoothly.

This blog shows you how you can test your JAX-RS endpoints running on Payara Micro with MicroProfile Testing.

What is TestContainers?

One of the major obstacles in integration testing is the setup of 3rd party systems. If your application uses a database, monitoring system, or other micro-services, they need to be ready and in a well-known state when you execute your test.

You can, of course, use some mocks and stubs to simulate the behavior, but these components should behave realistically and setting these up can also be very time-consuming.

With Docker Containers, systems can be started and removed easily and require no need to install them upfront. But the TestContainers framework does more than just starting and stopping a container for you during the test execution. You can define a wait strategy to determine when the container is ready and your test can start, and it has also predefined containers for databases, Kafka, NoSQL, etc...

When using with JUnit 5 Jupiter test engine, it is also highly configurable and extensible. And that is what MicroProfile Testing uses to make testing a JAX-RS resource so simple.

MicroProfile Testing

MicroProfile Testing is part of the tool set which makes working with the MicroProfile specifications even easier. You can find all those tools under the MicroShed umbrella. Have a look at the GitHub repository which groups them all.

So, let us go over the steps to test your JAX-RS endpoint.

First, we need to add a few maven dependencies to our project. The first one is the MicroShed Testing dependency.

<dependency>
<groupId>org.microshed</groupId>
<artifactId>microshed-testing-testcontainers</artifactId>
<version>0.4.1</version>
<scope>test</scope>
</dependency>

This dependency also brings in the TestContainers dependency, but also many features that make testing very easy.

As mentioned, with TestContainers, you can define the wait strategy but also the exposed ports. When you run your application on Payara Micro during the test, these should be configured according to the runtime. But all of that is taken care of for you in the Payara Micro plugin for MicroShed testing.

<dependency>
<groupId>org.microshed</groupId>
<artifactId>microshed-testing-payara-micro</artifactId>
<version>0.4.1</version>
<scope>test</scope>
</dependency>

Now, let us have a look at the JAX-RS endpoint we like to test. It is a hello world style of example, but of course, any kind of endpoint can be tested.

@Path("/hello")
@ApplicationScoped
public class HelloWorldResource {

@GET
public String sayHello() {
return "Hello World from " + getName();
}

private String getName() {
String instanceName = null;
try {
instanceName = InetAddress.getLocalHost().getHostName();
} catch (Exception e) {
e.printStackTrace(); // not production style.
}
return Optional.ofNullable(instanceName).orElse("<unknown>");
}
}

The reason why we include the hostname in the response is to prove to you that the execution is performed remotely. But more on that when we have a look at the test class.

@MicroShedTest
public class HelloWorldResourceIT {

@Container
public static MicroProfileApplication app = new MicroProfileApplication();

@Inject
public static HelloWorldResource helloWorldResource;

@Test
public void sayHello() throws IOException {
String data = helloWorldResource.sayHello();

assertThat(data).startsWith("Hello World");
System.out.println(data);

}

}

The first magic annotation is the @MicroShed one. It is defined as a JUnit5 extension and makes some of the nice features of MicroProfile Testing possible. One thing it does is the possibility of the 'injection of the JAX-RS resource class'.

In practice, a dynamically generated proxy is injected which calls the real application deployed in the Docker container using the information on the JAX-RS endpoint, like path and MediaType, but also from the MicroShed plugin, Payara Micro in our case.

So it looks like a local call, but in fact, it performs an HTTP call to the deployed endpoint. And all boilerplate to make this happen, define the endpoint and conversion of parameters to JSON for example, is done for you. This is also the reason why I included the hostname in the response, so you can see that the request is handled by the application within the Docker Container.

The `MicroProfileApplication` variable seems very basic, but again, a lot of things happen in the background. For starters, it searches for a Dockerfile, which you might have defined in the project, and which one you would use in production, and if not found - one is dynamically generated based on the war file in your project.

This way, you can either use the exact same Docker Container which you will use in production for the test. And if you didn't define one, it still works in combination with TestContainer. Environment variables, to define some configuration parameters, can be added to the initialisation.

Furthermore, there is no need for defining port mappings and ready checks. They all come from the Payara Micro plugin (but can be overwritten of course if needed in specific cases).

Simple Endpoint Testing for Payara Platform

With MicroProfile Testing, verifying the response of a JAX-RS endpoint becomes easy. Your application id started through the help of a Docker Container and 3rd party dependencies can be started alongside your application container. No upfront installation is required and the state is always well-known.

With the help of some clever proxy functionality, the test looks like a simple method call which is transformed to a remote call to your application endpoint and all conversion to JSON, for instance, are handled in the background.

The MicroShed Testing plugin for Payara Server and Payara Micro makes testing endpoints as simple as possible.

 

Comments