users@jersey.java.net

[Jersey] Re: jersey-client - Why final methods in ClientFilter???

From: Matt Bertolini <viper2843_at_gmail.com>
Date: Mon, 23 Jul 2012 15:18:12 -0400

Hi,

Thanks for replying. I have created a small example to demonstrate the
issue.

Here is a small example client filter and corresponding unit test:

public class ExampleClientFilter extends ClientFilter {
    @Override
    public ClientResponse handle(ClientRequest clientRequest) throws
ClientHandlerException {
        MultivaluedMap<String, Object> headers = clientRequest.getHeaders();
        headers.putSingle("X-Example-Header", "Hello World");
        return this.getNext().handle(clientRequest); // getNext() throws a
null pointer.
    }
}

public class ExampleClientFilterTest {
    @Test
    public void testHandle() {
        MultivaluedMap<String, Object> headers = new
StringKeyIgnoreCaseMultivaluedMap<Object>();
        ClientRequest mockClientRequest = Mockito.mock(ClientRequest.class);
        Mockito.when(mockClientRequest.getHeaders()).thenReturn(headers);
        ExampleClientFilter filter = new ExampleClientFilter();
        ClientResponse response = filter.handle(mockClientRequest);
        Assert.assertTrue(headers.containsKey("X-Example-Header"));
        // ...
    }
}

In order to unit test this class, I need to verify that the example header
was set in the request header map. I mock the ClientRequest object so I can
pass a header map to the mock and check it after the map. The problem
arrises in the last line of the filter. When I call getNext(), it will
throw a NullPointerException since the setNext() method can't be called. If
getNext() was not final, I could do a partial mock on my client filter and
return a mock ClientHandler object. The other way to fix this would be to
call setNext() but it is both final and package private so I have no
visibility to the method.

Since I must call getNext() to continue the filter chain, I have no way of
making this test not error. I hope this helps demonstrate the problem.
Thanks again for your help!

-Matt-

On Mon, Jul 23, 2012 at 11:24 AM, Jakub Podlesak
<jakub.podlesak_at_oracle.com>wrote:

> Hi,
>
> i do not see why having get/setNext final should block you from being able
> of testing your own client
> filters. These methods are only used internally to build the client filter
> chain. Could you please elaborate?
>
> Thanks,
>
> ~Jakub
>
>
> On 7/20/12 3:57 PM, viper2843_at_gmail.com wrote:
>
>> I have been using Jersey client to connect to a REST API. Everything
>> was going great until I started to write my unit tests. I can't unit
>> test my client filters because the abstract class ClientFilter has some
>> methods that are final: specifically getNext() and setNext(). I can't
>> mock final methods so I can't finish my test of these classes. Is there
>> any particular reason why these methods are marked as final? Thanks.
>>
>>
>>
>