Skip to content

Instantly share code, notes, and snippets.

@pram
Last active August 29, 2015 14:28
Show Gist options
  • Save pram/3bd1c994e9bd78c96400 to your computer and use it in GitHub Desktop.
Save pram/3bd1c994e9bd78c96400 to your computer and use it in GitHub Desktop.
AbstractJerseyTest
import static org.junit.Assert.fail;
import java.io.File;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriBuilder;
import org.junit.Before;
import org.junit.BeforeClass;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.WebAppDescriptor;
import com.sun.jersey.test.framework.spi.container.TestContainerException;
/**
* Base for unit-integration testing of REST web services based on Jersey (v. 1.9).
*
* What it does:
* <ul>
* <li>Configures Jersey logging to log detailed messages into /tmp/kodee-jersey-test.log
* <li>Starts Jersey with detailed request matching logs returned to the caller in the
* response headers (see {@link ClientResponse#getHeaders()})
* </ul>
*
* <h3>Usage</h3>
* Typically you would use something like this:
* <pre><code>{@code
* ClientResponse resp = resource().path("users").path(userId)
.type(MediaType.APPLICATION_JSON)
.delete(ClientResponse.class);
* }</code></pre>
*
* @see #assertHttpStatus(Status, ClientResponse)
* @see JerseyTest#resource()
*/
public abstract class AbstractJerseyTest extends JerseyTest {
// not really important as long as resource() is used instead of constructing the URL manually
protected static final String CONTEXT_PATH = "myTestJerseyApp";
/** The package containing the Jersey Resources (or semicolon-separated packages). */
protected static final String REST_SERVICES_PACKAGE = "com.example.rest_services";
private static int port;
@BeforeClass
public static void initDetailedJerseyLoggingIntoFile() throws Exception {
String tmpFileDirectory = System.getProperty("java.io.tmpdir");
File logFile = new File(tmpFileDirectory, "my-jersey-test.log");
Logger.getLogger("").addHandler(new FileHandler(logFile.getPath()));
Logger.getLogger("com.sun.jersey").setLevel(Level.FINEST);
System.out.println(AbstractJerseyTest.class.getSimpleName() + ": Jersey logs in " + logFile);
}
public AbstractJerseyTest() throws TestContainerException {
super(new WebAppDescriptor
.Builder(REST_SERVICES_PACKAGE)
.contextPath(CONTEXT_PATH)
.initParam("com.sun.jersey.config.feature.Trace", "true")
.initParam("com.sun.jersey.api.json.POJOMappingFeature", "true")
.build());
System.out.println("FYI: The Jersey Resources are available at " +
UriBuilder.fromUri(getBaseURI()).path(CONTEXT_PATH).build().toASCIIString());
}
/**
* Make sure that {@link JerseyTest#setUp()} is called by preventing
* subclasses from overriding it without callin it.
*/
@Before
@Override
public final void setUp() throws Exception {
super.setUp();
}
/**
* To do: Find a free port to be used for the server to avoid possible
* conflicts. The port class field must be set before the constructor is called.
* <p>
* Ex.: <code>{@code new ServerSocket(0).getLocalPort(); // and close it...; perhaps call setReuseAddress(true)}</code>
*
* @see #getPort(int)
* @see <a href="http://stackoverflow.com/questions/434718/sockets-discover-port-availability-using-java">StackOverflow: Sockets: Discover port availability using Java</a>
*/
@BeforeClass
public static void findFreePort() {
port = 9998; // Use some cleverness to detect a free port ...
}
/**
* Override to force JerseyTest to use the port we want instead of the default one.
*/
@Override
protected final int getPort(int defaultPort) {
return port;
}
/**
* Verify that the response's status is as expected, provide useful error message if not, including
* the response body (that might carry some details of the failure).
* @param expectedStatus (required) What status you expected; example: {@link Status#OK}
* @param actualResponse (required) Response from <code>{@code resource().path("exampleResource").get(ClientResponse.class);}</code>
*/
public static void assertHttpStatus(final Status expectedStatus, final ClientResponse actualResponse) {
int actualStatus = actualResponse.getStatus();
if (actualStatus != expectedStatus.getStatusCode()) {
String responseBody = actualResponse.getEntity(String.class);
fail("Expected status " + expectedStatus.getStatusCode() + " but got " + actualStatus
+ "; response body: '" + responseBody + "'" + "\nheaders:" + actualResponse.getHeaders());
}
}
}
Test case for ProductResource
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
import java.io.UnsupportedEncodingException;
import org.junit.Test;
import static org.junit.Assert.*;
import com.sun.jersey.test.framework.WebAppDescriptor;
import com.sun.jersey.test.framework.spi.container.http.HTTPContainerFactory;
import java.math.BigDecimal;
import org.model.Product;
import javax.ws.rs.core.MediaType;
/** *
* @author Kamal Hossain
*/
public class ProductServiceTest extends JerseyTest {
public static final String PACKAGE_NAME = "org.resources";
private WebResource ws;
public ProductServiceTest() {
super(new WebAppDescriptor.Builder(PACKAGE_NAME).build());
}
@Override
protected TestContainerFactory getTestContainerFactory() {
return new HTTPContainerFactory();
}
@Test
public void testProductResponse() throws UnsupportedEncodingException {
ws = resource().path("product/kamal");
ClientResponse response = ws.accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
assertEquals(200, response.getStatus());
System.out.println(response.getStatus());
}
@Test
public void testProductPrice() throws UnsupportedEncodingException {
ws = resource().path("product/kamal");
Product prod = ws.accept(MediaType.APPLICATION_XML).get(Product.class);
assertEquals(BigDecimal.valueOf(120), prod.getPrice());
}
}
Test case for ProductsResource
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
import java.io.UnsupportedEncodingException;
import org.junit.Test;
import static org.junit.Assert.*;
import com.sun.jersey.test.framework.WebAppDescriptor;
import com.sun.jersey.test.framework.spi.container.http.HTTPContainerFactory;
import org.model.Product;
import java.util.Collection;
import java.util.List;
import javax.ws.rs.core.MediaType;
/** *
* @author kamal hossain
*/
public class ProductsServiceTest extends JerseyTest {
public static final String PACKAGE_NAME = 'org.resources';
private WebResource ws;
public ProductsServiceTest() {
super(new WebAppDescriptor.Builder(PACKAGE_NAME).build());
}
@Override
protected TestContainerFactory getTestContainerFactory() {
return new HTTPContainerFactory();
}
@Test
public void testProductResponse() throws UnsupportedEncodingException {
ws = resource().path("product/kamal");
ClientResponse response = ws.accept(MediaType.APPLICATION_XML).get(ClientResponse.class);
assertEquals(200, response.getStatus());
System.out.println(response.getStatus());
}
@Test
public void testProductList() throws UnsupportedEncodingException {
ws = resource().path("products");
GenericType<Collection<Product>> genericType = new GenericType<Collection<Product>>(){};
List<Product> wsResult = (List<Product>) ws.accept(MediaType.APPLICATION_XML).get(genericType);
assertEquals(2, wsResult.size());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment