Wiki Markup |
---|
{span:style=font-size:2em;font-weight:bold} JAX-RS Testing{span} |
Table of Contents |
---|
JAX-RS endpoints can be easily tested using the embedded Jetty or CXF Local Transport.
Embedded Jetty
Code Block | ||||
---|---|---|---|---|
| ||||
import javax.ws.rs.core.Response;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
import org.junit.Test;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import custom.MyJaxrsResource;
import custom.Book;
public class JAXRSTest extends Assert {
private final static String ENDPOINT_ADDRESS = "http://localhost:8080/rest";
private final static String WADL_ADDRESS = ENDPOINT_ADDRESS + "?_wadl";
private static Server server;
@BeforeClass
public static void initialize() throws Exception {
startServer();
waitForWADL();
}
private static void startServer() throws Exception {
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(MyJaxrsResource.class);
List<Object> providers = new ArrayList<Object>();
// add custom providers if any
sf.setProviders(providers);
sf.setResourceProvider(MyJaxrsResource.class.class,
new SingletonResourceProvider(new MyJaxrsResource(), true));
sf.setAddress(ENDPOINT_ADDRESS);
server = sf.create();
}
// Optional step - may be needed to ensure that by the time individual
// tests start running the endpoint has been fully initialized
private static void waitForWADL() throws Exception {
WebClient client = WebClient.create(WADL_ADDRESS);
// wait for 20 secs or so
for (int i = 0; i < 20; i++) {
Thread.currentThread().sleep(1000);
Response response = client.get();
if (response.getStatus() == 200) {
break;
}
}
// no WADL is available yet - throw an exception or give tests a chance to run anyway
}
@AfterClass
public static void destroy() throws Exception {
server.stop();
server.destroy();
}
@Test
public void testGetBookWithWebClient() {
WebClient client = WebClient.create(ENDPOINT_ADDRESS);
client.accept("text/xml");
client.path("somepath");
Book book = client.get(Book.class);
assertEquals(123L, book.getId());
}
@Test
public void testGetBookWithProxy() {
MyJaxrsResource client = JAXRSClientFactory.create(ENDPOINT_ADDRESS, MyJaxrsResource.class);
Book book = client.getBook();
assertEquals(123L, book.getId());
}
}
|
...
Starting from CXF 2.6.2 it is possible to use CXF Local Transport for testing the JAX-RS endpoints and clients.
This avoids the need to start an embedded servlet container and the tests will run faster.
Code Block | ||||
---|---|---|---|---|
| ||||
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-local</artifactId> <version>3.0.0</version> </dependency> |
Example:
Code Block | ||||
---|---|---|---|---|
| ||||
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
import org.apache.cxf.transport.local.LocalConduit;
import org.junit.Test;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.AfterClass;
import custom.MyJaxrsResource;
import custom.Book;
public class JAXRSTest extends Assert {
private final static String ENDPOINT_ADDRESS = "local://books";
private static Server server;
@BeforeClass
public static void initialize() throws Exception {
startServer();
}
private static void startServer() throws Exception {
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(MyJaxrsResource.class);
List<Object> providers = new ArrayList<Object>();
// add custom providers if any
sf.setProviders(providers);
sf.setResourceProvider(MyJaxrsResource.class.class,
new SingletonResourceProvider(new MyJaxrsResource(), true));
sf.setAddress(ENDPOINT_ADDRESS);
server = sf.create();
}
@AfterClass
public static void destroy() throws Exception {
server.stop();
server.destroy();
}
@Test
public void testGetBookWithWebClientDirectDispatch() {
WebClient client = WebClient.create(ENDPOINT_ADDRESS);
WebClient.getConfig(client).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);
client.accept("text/xml");
client.path("somepath");
Book book = client.get(Book.class);
assertEquals(123L, book.getId());
}
@Test
public void testGetBookViaPipe() {
WebClient client = WebClient.create(ENDPOINT_ADDRESS);
client.accept("text/xml");
client.path("somepath");
Book book = client.get(Book.class);
assertEquals(123L, book.getId());
}
@Test
public void testAddBookWithProxyDirectDispatch() {
MyJaxrsResource client = JAXRSClientFactory.create(ENDPOINT_ADDRESS, MyJaxrsResource.class);
WebClient.getConfig(client).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);
Book book = client.echoBook(new Book(123));
assertEquals(123L, book.getId());
}
}
|
...
Alternatively, the address can be set as a relative value such as "/books", with the server and client transportId attribute set to
"http://cxf.apache.org/transports/local". In this case, when creating the clients, use JAXRSClientFactoryBean:
Code Block | ||||
---|---|---|---|---|
| ||||
private static void startServer() throws Exception {
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setTransportId(LocalTransportFactory.TRANSPORT_ID);
sf.setAddress("/books");
sf.setResourceClasses(MyJaxrsResource.class);
server = sf.create();
}
@Test
public void testProxyPipedDispatchGet() throws Exception {
JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
bean.setTransportId(LocalTransportFactory.TRANSPORT_ID);
bean.setAddress("/books");
bean.setServiceClass(MyJaxrsResource.class);
MyJaxrsResource localProxy = bean.create(MyJaxrsResource.class);
Book book = localProxy.getBook("123");
assertEquals(123L, book.getId());
}
|