Bharath ABK
Bharath ABK

Reputation: 444

Unit Test CXF JAX-RS implementation without deploying to server

Working on a JAX-RS client using CXF.

Requirement is to test the service side code from unit test case with the help of a test client without deploying the rest service to a server

REST Service we implemented use HTTP headers to pass some information to the WS methods.

All the implementations I came across, so far, have services deployed to a server.

Examples I tried to create a JAX-RS client

        WebClient client = WebClient.create(ENDPOINT_ADDRESS);

and

RestWSInterafce proxy = JAXRSClientFactory.create(ENDPOINT_ADDRESS, RestWSInterafce.class);
    Client client = WebClient.client(proxy);
    WebClient httpClient = WebClient.fromClient(client);

I tried configuring a CXF-Jetty implementation but didn't had any luck. Below is a snapshot from the Spring application context file

 <import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-extension-http-jetty.xml" />

<jaxrs:client id="restWSClient" address="${server.address}" serviceClass="com.xyz.rs.RestWSInterface">
</jaxrs:client>

Is it possible to test without having the rest services deployed to a server?


Edit

My main concern while posting this question is to test the method which expects HttpHeaders elements to be passed in the context. Consider the below GET method from my interface.

@GET
@Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
@Path("/getMessage")
public Response getMessage(@Context HttpHeaders headers);

To Unit test this method, instead of calling the interface by deploying the application to the server, I wrote test case to call the implementation class directly and pass an implementor to HttpHeader as input. This solved my issue of unit testing the ws methods without deploying to the server.

public class HttpHeadersImpl implements HttpHeaders {

private MultivaluedMap<String, String> multivaluedMap;

public void setRequestHeaders(MultivaluedMap<String, String> multivaluedMap) {
    this.multivaluedMap = multivaluedMap;
}

@Override
public MultivaluedMap<String, String> getRequestHeaders() {
    return multivaluedMap;
}
}

Upvotes: 2

Views: 2588

Answers (1)

pedrofb
pedrofb

Reputation: 39241

You can launch programmaticaly a CXF server from your unit tests without deploying into a server

JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(TestServiceImpl.class);
sf.setAddress("http://localhost:8080/testrs");
sf.create();  

To start the endpoint you will need the cxf-rt-transports-http-jetty dependency

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http-jetty</artifactId>
    <version>3.1.6</version>
</dependency>

The server could be the real or simulated only for testing. With the WebClient you can test the http transport.

If you work with CXF and Spring, you also can initialize the full context using ClassPathXmlApplicationContext and inject the rest server to the unit test client. In this case you can test the services without http transport

Upvotes: 1

Related Questions