Skip to content

Instantly share code, notes, and snippets.

@natereed
Last active December 30, 2016 00:35
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natereed/6023281 to your computer and use it in GitHub Desktop.
Save natereed/6023281 to your computer and use it in GitHub Desktop.
Stubbing/mocking Jersey Client. Inspired by WebMock.
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
public class CRMClientTest {
private CRMClient crmClient;
private StubbedClientHandler clientHandler;
@Before
public void setup() {
clientHandler = new StubbedClientHandler();
crmClient = new CRMClient(clientHandler);
}
@Test
public void itShouldPostToTheCRM() {
Company company = new Company();
Map<String, String> headerParams = new HashMap<String, String>();
MethodStub stubbedMethod = clientHandler.stubMethod("/rest/crm/accounts", "POST").withHeaderParams(headerParams).toRespondWith("Success!", 200).build();
crmClient.postAccountToCrm(headerParams, company);
clientHandler.verifyMethod(stubbedMethod);
}
}
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.ClientRequest;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.TerminatingClientHandler;
import com.sun.jersey.core.header.InBoundHeaders;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseWriter;
import org.junit.Assert;
import javax.ws.rs.core.MultivaluedMap;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class StubbedClientHandler extends TerminatingClientHandler {
Map<MethodStubKey, MethodStub> stubbedMethods = new HashMap<MethodStubKey, MethodStub>();
public class MethodStubBuilder {
private int statusCode;
private String response;
private String path;
private String method;
private Map<String, String> headerParams;
public MethodStubBuilder() {}
public MethodStubBuilder toRespondWith(String response, int statusCode) {
this.response = response;
this.statusCode = statusCode;
return this;
}
public MethodStubBuilder withHeaderParams(Map<String, String> headerParams) {
this.headerParams = headerParams;
return this;
}
public MethodStubBuilder path(String path) {
this.path = path;
return this;
}
public MethodStubBuilder method(String method) {
this.method = method;
return this;
}
public MethodStub build() {
MethodStub stub = new MethodStub(path, method, response, statusCode);
stub.setHeaderParams(headerParams);
stubbedMethods.put(stub.getKey(), stub);
return stub;
}
}
public MethodStubBuilder stubMethod(String path, String method) {
return new MethodStubBuilder().path(path).method(method);
}
public boolean verifyMethod(String path, String method, String query) {
MethodStub stub = stubbedMethods.get(new MethodStubKey(method, path, query));
if (stub == null)
throw new RuntimeException("No stub " + stub.toString() + "exists!");
return verifyMethod(stub);
}
public boolean verifyMethod(MethodStub stub) {
if (!stub.wasCalled()) {
throw new RuntimeException("Stub " + stub.toString() + " was not called!");
}
return true;
}
@Override
public ClientResponse handle(ClientRequest clientRequest) throws ClientHandlerException {
String method = clientRequest.getMethod();
Object entity = clientRequest.getEntity();
String path = clientRequest.getURI().getPath();
String query = clientRequest.getURI().getQuery();
MultivaluedMap<String, Object> headers = clientRequest.getHeaders();
MethodStub stubbedMethod = stubbedMethods.get(new MethodStubKey(method, path, query));
if (stubbedMethod != null) {
compareHeaders(headers, stubbedMethod.getHeaderParams());
stubbedMethod.setWasCalled(true);
ClientResponse response = new ClientResponse(stubbedMethod.getStatusCode(),
getInBoundHeaders(clientRequest.getMetadata()),
new ByteArrayInputStream(stubbedMethod.getResponse().getBytes()),
getMessageBodyWorkers() );
return response;
}
else {
throw new RuntimeException("No method stub for unexpected call " + method + ", " + path + ", " + query);
}
}
// Check for stub headers in request (not vice-versa, since there can be a lot of other headers we don't care about)
private void compareHeaders(MultivaluedMap<String, Object> requestHeaders, Map<String, String> stubHeaderParams) {
if (stubHeaderParams !=null) {
for (String key : stubHeaderParams.keySet()) {
Assert.assertEquals(requestHeaders.get(key), stubHeaderParams.get(key));
}
}
}
private static class TestContainerResponseWriter implements ContainerResponseWriter {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
public OutputStream writeStatusAndHeaders(long contentLength,
ContainerResponse response) throws IOException {
return baos;
}
public void finish() throws IOException {
}
}
private InBoundHeaders getInBoundHeaders(MultivaluedMap<String, Object> outBound) {
InBoundHeaders inBound = new InBoundHeaders();
for (Map.Entry<String, List<Object>> e : outBound.entrySet()) {
for (Object v : e.getValue()) {
inBound.add(e.getKey(), ClientRequest.getHeaderValue(v));
}
}
return inBound;
}
}
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.MediaType;
import java.io.InputStream;
import java.io.StringWriter;
public class StubbedClientHandlerTest {
private StubbedClientHandler stubbedClientHandler;
private Client client;
@Before
public void setup() {
stubbedClientHandler = new StubbedClientHandler();
client = new Client(stubbedClientHandler);
}
@Test
public void testStubbedMethodShouldRespondWithStubbedResponse() throws Exception {
MethodStub stub = stubbedClientHandler.stubMethod("/rest/crm/accounts", HttpMethod.POST).toRespondWith("Success!", 200).build();
WebResource resource = client.resource("http://localhost:5555").path("/rest/crm/accounts");
ClientResponse response = resource.type(MediaType.APPLICATION_JSON).post(ClientResponse.class, "{}");
Assert.assertEquals(200, response.getStatus());
StringWriter writer = new StringWriter();
InputStream is = response.getEntityInputStream();
IOUtils.copy(is, writer);
Assert.assertEquals("Success!", writer.toString());
stubbedClientHandler.verifyMethod(stub);
}
}
@ftardif
Copy link

ftardif commented Feb 26, 2014

I'd like to use your Jersey Client mocking mechanism, but could it possible you forgot to commit you MethodStubKey and MethodStub classes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment