users@jersey.java.net

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

From: Matt Bertolini <viper2843_at_gmail.com>
Date: Sun, 29 Jul 2012 13:53:48 -0400

It is an understandable question to ask James. While I appreciate the
"Growing Object Oriented Software" authors argument about only mocking
types that you own and try to follow it the best I can, in the real world
things are rarely as black and white as they are in books. I will elaborate
on my motivations.

The use of the ClientFilter is to provide an ability for developers to take
code that would normally be repeated in their request methods and abstract
it out into reusable manner. If these filters cannot be tested, then the
code will be moved to a place where it can be, and this breaks the "don't
repeat yourself" principles of object-oriented design. So we have two
academic concepts that contradict each other. I will take "don't repeat
yourself" over not mocking a third party object almost every time because
it maintains clean code.

The implementation of ClientFilter already has a code smell in that it uses
inheritance instead of composition. If we are to take the author's argument
to its extreme, then any class that implements a third-party interface
would not be unit tested. I don't buy that.

Take Java's servlet filters for example. These provide a similar facility
to the client filter and they are implemented using interfaces entirely,
thus eliminating the problem of the parent's implementation interfering
with a unit test. Ultimately, I think that the client filter implementation
needs to be altered to correct the code smell.

The author argues that you should create an adapter layer to abstract out
the third-party code. I agree with this 100% and have done that in the case
of the vast majority of the Jersey client classes. The nature of the client
filter chain makes it very difficult make such an abstraction.

The bottom line is, if I can unit test my client filters, cover 80% of the
cases that might cause problems, and set up a facility for me to easily
expand on those tests when bugs are found/fixed in a quick and reliable
fashion, then I am willing to bend a couple of rules found in a book to
make that happen.

This brings me back to my original question: why is the getNext() method
final? Making something final is a very serious statement to the user of an
API so there should be some reason why the method was marked that way. I am
wondering why.

--Matt--

On Sun, Jul 29, 2012 at 10:57 AM, James Shaw <js102_at_zepler.net> wrote:

> On 23 July 2012 20:18, Matt Bertolini <viper2843_at_gmail.com> wrote:
>
>>
>> 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 ClientRequestobject 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.
>>
>>
> Do you really want to be unit testing when you're integrating with code
> you don't own? Take a look at "Only Mock Types That You Own" from Growing
> Object Oriented Software.
>
>
>