Test JAX-RS REST API with ResteasyTest

ResteasyTest provides a convenient way to test JAX-RS resources in your JUnit test. It allows you to define your REST endpoints in your tests classes and verify that the exposed resources work properly. ResteasyTest is similar to JerseyTest but uses Resteasy as provider and is not as feature rich. The dependencies used are the same as in JBoss EAP / WildFly. These are undertow as ServletContainer, Resteasy as JAX-RS implementation and jackson 2 for JSON support.

How does it work

ResteasyTest starts undertow using a free port on your system. In your JUnit test you define JAX-RS endpoints which are deployed to undertow. These endpoints can be tested with the methods post() and get() which use ResteasyClient to send the requests to the started undertow instance.

Setup dependencies

Because ResteasyTest isn’t available as Maven dependency in the Maven Central Repository, you need to include it in your project yourself. If demanded, I will make the effort to upload it.

To get ResteasyTest running, you need to include the following Maven dependencies in your <dependencies></dependencies>section:

<dependency>
    <groupId>io.undertow</groupId>
    <artifactId>undertow-servlet</artifactId>
    <version>${undertow.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>io.undertow</groupId>
    <artifactId>undertow-core</artifactId>
    <version>${undertow.version}</version>
    <scope>test</scope>    
</dependency>
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-undertow</artifactId>
    <version>${resteasy.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxrs</artifactId>
    <version>${resteasy.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jackson2-provider</artifactId>
    <version>${resteasy.version}</version>
    <scope>test</scope>
</dependency>

To add JAXB annotation support, you might want to add these dependency too:

<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-jaxb-annotations</artifactId>
    <version>${jackson.version}</version>
    <scope>test</scope>
</dependency>

For java.time support, you need to this dependency, if the used Jackson version is below 2.8.5. This is the case for JBoss EAP 7.0 or WildFly 10.

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>${jackson.version}</version>
    <scope>test</scope>
</dependency>

If your Jackson version is above 2.8.5 (like in JBoss EAP 7.1+), you need to use the jackson-modules-java8. This isn’t tested yet.

JBossEAP 7.0 / WildFly 10 dependency versions

For JBoss EAP 7.0 and WildFly 10 (upstream project) use the following dependency versions:

<properties>
    <resteasy.version>3.0.16.Final</resteasy.version>
    <undertow.version>1.3.21.Final</undertow.version>
    <jackson.version>2.6.3</jackson.version>
</properties>

So you use the same artifacts and versions as in your application server.

JBoss EAP 7.1 / WildFly 11 dependency versions

For JBoss EAP 7.1 and WildFly 11 (upstream project) use the these dependency versions. This setup isn’t tested from me yet but should work. If you use additional Jackson modules, make sure these are compatible with these versions.

<properties>
    <resteasy.version>3.0.24.Final</resteasy.version>
    <undertow.version>1.3.25.Final</undertow.version>
    <jackson.version>2.8.9</jackson.version>
</properties>

Usage

To use ResteasyTest, you need to include ResteasyTest.java in your maven module where you want to test a JAX-RS resource.

To test a JAX-RS endpoint, create a test class and inherit the now included ResteasyTest.java class. Override the method configureResource() to add an instance of your REST endpoint to ResteasyTest.

public class RestEndpointTest extends ResteasyTest {
    @Override
    public List<Object> configureResources() {
        return Stream.of(new RestEndpoint()).collect(Collectors.toList());
    }
}

To declare a provider (eg. for custom field mappings) override configureProvider().

@Override
public List<Object> configureProvider() {
    return Stream.of(new ObjectMapperContextResolver()).collect(Collectors.toList());
}

Now you can simply use get() and post() to test your endpoint:

@Test
public void testGetPojo() {
    Pojo expectedPojo = new Pojo("Hello");
    Pojo actualPojo = get("/resource/pojo", Pojo.class);
    Assert.assertEquals(expectedPojo, actualPojo);
}
@Test
public void testPostPojo() {
    Pojo world = new Pojo("World");
    Pojo response = post("/resource/post", world, Pojo.class);
    Assert.assertEquals("Hello World", response.getName());
}

To get the result without deserialization, simply put String.class as last argument to post() or get(). You find complete examples in ResteasyTestTest.java.

CDI Support

ResteasyTest doesn’t support CDI directly. But you can use cdi-unit to inject a REST endpoint in your JUnit test and return it in the overriden configureResources() method. But for the most cases I would recommend using mockito with its MockitoJUnitRunner.class to satisfy @Inject points. cdi-unit is slow because it’s using Weld. I think the purpose should be to test your REST endpoints serialization/deserialization and URL only.

Source

GitHub: https://github.com/niiku/resteasy-test

Leave a Reply

Close Menu