Home » Java » Enterprise Java » Jersey Client: Testing external calls

About Mark Needham

Mark Needham

Jersey Client: Testing external calls

Jim and I have been doing a bit of work over the last week which involved calling neo4j’s HA status URI to check whether or not an instance was a master/slave and we’ve been using jersey-client.
The code looked roughly like this:

class Neo4jInstance {
    private Client httpClient;
    private URI hostname;

    public Neo4jInstance(Client httpClient, URI hostname) {
        this.httpClient = httpClient;
        this.hostname = hostname;

    public Boolean isSlave() {
        String slaveURI = hostname.toString() + ":7474/db/manage/server/ha/slave";
        ClientResponse response = httpClient.resource(slaveURI).accept(TEXT_PLAIN).get(ClientResponse.class);
        return Boolean.parseBoolean(response.getEntity(String.class));

While writing some tests against this code we wanted to stub out the actual calls to the HA slave URI so we could simulate both conditions and a brief search suggested that mockito was the way to go.

We ended up with a test that looked like this:

public void shouldIndicateInstanceIsSlave() {
    Client client = mock( Client.class );
    WebResource webResource = mock( WebResource.class );
    WebResource.Builder builder = mock( WebResource.Builder.class );

    ClientResponse clientResponse = mock( ClientResponse.class );
    when( builder.get( ClientResponse.class ) ).thenReturn( clientResponse );
    when( clientResponse.getEntity( String.class ) ).thenReturn( "true" );
    when( webResource.accept( anyString() ) ).thenReturn( builder );
    when( client.resource( anyString() ) ).thenReturn( webResource );

    Boolean isSlave = new Neo4jInstance(client, URI.create("http://localhost")).isSlave();


which is pretty gnarly but does the job.

I thought there must be a better way so I continued searching and eventually came across this post on the mailing list which suggested creating a custom ClientHandler and stubbing out requests/responses there.

I had a go at doing that and wrapped it with a little DSL that only covers our very specific use case:

private static ClientBuilder client() {
    return new ClientBuilder();

static class ClientBuilder {
    private String uri;
    private int statusCode;
    private String content;

    public ClientBuilder requestFor(String uri) {
        this.uri = uri;
        return this;

    public ClientBuilder returns(int statusCode) {
        this.statusCode = statusCode;
        return this;

    public Client create() {
        return new Client() {
            public ClientResponse handle(ClientRequest request) throws ClientHandlerException {
                if (request.getURI().toString().equals(uri)) {
                    InBoundHeaders headers = new InBoundHeaders();
                    headers.put("Content-Type", asList("text/plain"));
                    return createDummyResponse(headers);
                throw new RuntimeException("No stub defined for " + request.getURI());

    private ClientResponse createDummyResponse(InBoundHeaders headers) {
        return new ClientResponse(statusCode, headers, new ByteArrayInputStream(content.getBytes()), messageBodyWorkers());

    private MessageBodyWorkers messageBodyWorkers() {
        return new MessageBodyWorkers() {
            public Map<MediaType, List<MessageBodyReader>> getReaders(MediaType mediaType) {
                return null;

            public Map<MediaType, List<MessageBodyWriter>> getWriters(MediaType mediaType) {
                return null;

            public String readersToString(Map<MediaType, List<MessageBodyReader>> mediaTypeListMap) {
                return null;

            public String writersToString(Map<MediaType, List<MessageBodyWriter>> mediaTypeListMap) {
                return null;

            public <T> MessageBodyReader<T> getMessageBodyReader(Class<T> tClass, Type type, Annotation[] annotations, MediaType mediaType) {
                return (MessageBodyReader<T>) new StringProvider();

            public <T> MessageBodyWriter<T> getMessageBodyWriter(Class<T> tClass, Type type, Annotation[] annotations, MediaType mediaType) {
                return null;

            public <T> List<MediaType> getMessageBodyWriterMediaTypes(Class<T> tClass, Type type, Annotation[] annotations) {
                return null;

            public <T> MediaType getMessageBodyWriterMediaType(Class<T> tClass, Type type, Annotation[] annotations, List<MediaType> mediaTypes) {
                return null;

    public ClientBuilder content(String content) {
        this.content = content;
        return this;

If we change our test to use this code it now looks like this:

public void shouldIndicateInstanceIsSlave() {
    Client client = client().requestFor("http://localhost:7474/db/manage/server/ha/slave").
    Boolean isSlave = new Neo4jInstance(client, URI.create("http://localhost")).isSlave();

Is there a better way?

In Ruby I’ve used WebMock to achieve this and Ashok pointed me towards WebStub which looks nice except I’d need to pass in the hostname + port rather than constructing that in the code.


Reference: Jersey Client: Testing external calls from our JCG partner Mark Needham at the Mark Needham Blog blog.
(0 rating, 0 votes)
You need to be a registered member to rate this.
2 Comments Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
Email address:

Leave a Reply

2 Comments on "Jersey Client: Testing external calls"

newest oldest most voted
Notify of
Gerard Davison


If you make use of the Jersey class TerminatingClientHandler you can simplify this code quite a bit, here in the test class that I use in the wadl.java.net project:


And the same code, obviously slightly different, when using JAX-RS 2.0:


Hope this is helpful,



The second approach aside: How did you get the first one to even run? When I try mocking WebResource.Builder as you do up there, I get the following:

Cannot mock/spy class com.sun.jersey.api.client.WebResource$Builder
Mockito cannot mock/spy following:
– final classes
– anonymous classes
– primitive types

as WebResource.Builder is declared final.