Home » Java » java – JUnit Test with Mockito – How to Mock javax.ws.rs.client.ClientRequestContext?-Exceptionshub

java – JUnit Test with Mockito – How to Mock javax.ws.rs.client.ClientRequestContext?-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I have a class that implements javax.ws.rs.client.ClientRequestFilter:

public class CustomFilter implements ClientRequestFilter {

@Override
public void filter(ClientRequestContext context) throws IOException {
    URI newUri = ... //replace a new uri
    context.setUri(URI.create(newUri));

    if (context.getMethod == "POST") {
        context.setMethod("GET");
        context.getHeaders().putSingle("ID","some string");
    }
}

What I want is somehow to mock the ClientRequestContext. I want to compare that after calling the filter() function:

  1. The new uri is set correctly.
  2. The new http method is set correctly.
  3. A new header “ID” is set with “some string” for the context.

As I tried to figure out, I can only mock the getter methods, and I do not know how to mock ClientRequestContext properly and use my CustomerFilter class to call the real function filter() to change values of the ClientRequestContext object since it is an interface. Could you help me to achieve the 3 requirements?

How to&Answers:

The class ClientRequestFilter is an interface, so you can mock it either using the static Mockito.mock method or annotating the field as @Mock in the test. So, if you want to check if the setUri method is called, you should do the following in your test method:

CustomFilter customFilter = new CustomFilter();
customFilter.filter(context);
Mockito.verify(context, Mockito.once()).setUri(ArgumentMatchers.any(URI.class));

For older Mockito versions:

CustomFilter customFilter = new CustomFilter();
customFilter.filter(context);
Mockito.verify(context, Mockito.once()).setUri(Matchers.any());

You don’t have to verify that the underlying implementation is working. Since you are using an interface you will trust that the implementation that you will have at runtime is correct, because it is not necessary to test you dependencies. You simply have to be sure that the code you wrote is working and is forwarding requests to other classes.

In similar way you can test the other requirement:

Mockito.when(context.getMethod()).thenReturn("POST");
MultivaluedMap headers = Mockito.mock(MultivaluedMap.class);
Mockito.when(context.getHeaders()).thenReturn(headers);
CustomFilter customFilter = new CustomFilter();
customFilter.filter(context);
Mockito.verify(context, Mockito.once()).setUri(Matchers.any());
Mockito.verify(context, Mockito.once()).setMethod(Matchers.any());
Mockito.verify(context, Mockito.once()).getHeaders();

Answer:

You can use argument mockito matchers and/or argument captors. Or you cat write a stub for request context and spy on it:

package test;

import org.junit.Test;

import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import java.io.IOException;
import java.net.URI;

import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.CoreMatchers.*;
import static org.mockito.Mockito.*;

public class ClientRequestContextTest {

    abstract static class ClientRequestContextStub implements ClientRequestContext {
        MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
        URI uri = null;
        String method = null;
        ClientRequestContextStub(){}
        @Override public String getMethod() { return method; }
        @Override public void setMethod(String method) { this.method = method; }
        @Override public URI getUri() { return uri; }
        @Override public void setUri(URI uri) { this.uri = uri; }
        @Override public MultivaluedMap<String, Object> getHeaders() { return headers; }
    }

    static class CustomFilter implements ClientRequestFilter {
        private String newUri = null;
        CustomFilter(String newUri) { this.newUri = newUri; }
        @Override
        public void filter(ClientRequestContext context) throws IOException {
            context.setUri(URI.create(newUri));
            if (context.getMethod().equals("POST")) {
                context.setMethod("GET");
                context.getHeaders().putSingle("ID", "some string");
            }
        }
    }

    @Test
    public void checkCustomFilter() throws IOException {
        URI newUriValue = URI.create("https://user:[email protected]:12345/suffix");
        ClientRequestContext context = spy(ClientRequestContextStub.class);
        context.setUri(URI.create("localhost:8080"));
        context.setMethod("POST");
        assertThat(context.getMethod(), equalTo("POST"));
        assertThat(context.getUri().toString(), equalTo("localhost:8080"));
        assertThat(context.getHeaders().size(), equalTo(0));
        new CustomFilter(newUriValue.toString()).filter(context);
        assertThat(context.getMethod(), equalTo("GET"));
        assertThat(context.getUri(), equalTo(newUriValue));
        assertThat(context.getHeaders().size(), equalTo(1));
        assertThat(context.getHeaders().getFirst("ID").toString(), is("some string"));
    }
}