Testing private methods

michael_coxeter <mco <at> mwdata.dk>
2006-10-02 14:53:43 GMT

Hi Folks,
Is it good to test private methods or not?
Most people seem to think that private methods should be tested by
testing the public methods correctly. And this would seem like good
advice.
However, when it comes to refactoring is it nice to have tests on
all your code?
I recently looked at a refactoring a class which only had one public
method.
The tests that existed for the public method seemed a little brittle
as it is hard to perceive all the possibilities that need testing.
The code had many private methods and I was itching to refractor it.
So to make my job easier I moved the private methods into an
implementation class, made them public and wrote new tests for
these. Anyway the refactoring went well and I am pleased with the
result.
My new tests are somewhat linked to the implementation I chose for
the original public method.
Are they worth keeping around? Or are these an example of temporary
tests that have served a purpose and can now be thrown away?

Re: Testing private methods

Keith Ray <keith.ray <at> gmail.com>
2006-10-02 18:02:57 GMT

You've rediscovered the "iceberg class" code-smell and its remedy
"extract class(es)"
<http://www.artima.com/weblogs/viewpost.jsp?thread=125574>
<http://homepage.mac.com/keithray/blog/2006/04/15/>
If it's hard to test, it is poorly designed.
On 10/2/06, michael_coxeter <mco <at> mwdata.dk> wrote:
>
>
>
>
>
>
> Hi Folks,
>
> Is it good to test private methods or not?
>
> Most people seem to think that private methods should be tested by
> testing the public methods correctly. And this would seem like good
> advice.
>
> However, when it comes to refactoring is it nice to have tests on
> all your code?
>
> I recently looked at a refactoring a class which only had one public
> method.
>

RE: Testing private methods

Alan Baljeu <alanb <at> cornerstonemold.com>
2006-10-02 18:25:28 GMT

Michael Coxeter asked:
> Hi Folks,
>
> Is it good to test private methods or not?
>
> Most people seem to think that private methods should be
> tested by testing the public methods correctly. And this
> would seem like good advice.
>
> However, when it comes to refactoring is it nice to have
> tests on all your code?
It is always nice to have tests. I would only remove tests if they duplicate other tests,
or if they are testing dead code. In the latter case, I also delete the dead code.
>
> I recently looked at a refactoring a class which only had one
> public method.
>
> The tests that existed for the public method seemed a little
> brittle as it is hard to perceive all the possibilities that
> need testing.
It is hard to test complex behaviour. From a testing perspective, there is no difference
between your original class and a single monolithic method. Everyone knows long functions
are bad, but isn't lots of private methods are equally bad?
I think the solution is what you did. Then, keep your tests on the new class. That way, if
you need to change some function in the future, your tests will tell you if you broke
something in the process.

Re: Testing private methods

Hi,
which language do you use? C++ with friend method otherwise I think is
impossible to test private method. Can you explain better?
2006/10/2, michael_coxeter <mco <at> mwdata.dk>:
>
> Hi Folks,
>
> Is it good to test private methods or not?
>
> Most people seem to think that private methods should be tested by
> testing the public methods correctly. And this would seem like good
> advice.
>
> However, when it comes to refactoring is it nice to have tests on
> all your code?
>
> I recently looked at a refactoring a class which only had one public
> method.
>
> The tests that existed for the public method seemed a little brittle
> as it is hard to perceive all the possibilities that need testing.
>
> The code had many private methods and I was itching to refractor it.
> So to make my job easier I moved the private methods into an
> implementation class, made them public and wrote new tests for
> these. Anyway the refactoring went well and I am pleased with the
> result.
>

Re: Testing private methods

Hello michael, thank you for raising an interesting question. On
Monday, October 2, 2006, at 10:53:43 AM, you wrote:
> Is it good to test private methods or not?
I feel strongly that all methods need to be sufficiently covered by
tests ...
> Most people seem to think that private methods should be tested by
> testing the public methods correctly. And this would seem like good
> advice.
... and I prefer to test only through the public interface.
> However, when it comes to refactoring is it nice to have tests on
> all your code?
It is. Depending on how and what I'm refactoring, I might want more
tests on the private methods. At the same time, I consider a desire
to test a private method as an indication that the method or class
may need to be broken up a different way.
> I recently looked at a refactoring a class which only had one public
> method.
If I had a class with only one method, I would also think that to be
an indication that something was wrong somewhere ...
> The tests that existed for the public method seemed a little brittle
> as it is hard to perceive all the possibilities that need testing.

Re: Side Effect

Joshua Kerievsky wrote:
>Michael Feathers wrote:
>
>
>>It's a violation of the Command/Query Separation Principle. According
>>to the principle, a method should be a command or a query but not both.
>>If a method has a return value it shouldn't set state.
>>
>>It's a principle from Betrand Meyer, and definitely one that needs its
>>profile raised.
>>
>>CQSP is also a specific case of SRP applied to methods.
>>
>>
>>
>CQSP isn't mentioned by name, but does show up in this refactoring:
>http://www.refactoring.com/catalog/separateQueryFromModifier.html
>
>Are you seeing a need for a Side Effect smell?
>
>
I guess it depends on how it is described. If the description is too
general, we'd all refactor ourselves to Haskell
I wonder if there is catchier phrase for "unintended side-effect?"
Michael Feathers
www.objectmentor.com

Re: Side Effect

Shane Mingins <shane.mingins <at> gmail.com>
2006-10-02 19:58:08 GMT

Adverse Effect?
On 10/3/06, Michael Feathers <mfeathers <at> mindspring.com> wrote:
>
> Joshua Kerievsky wrote:
>
> >Michael Feathers wrote:
> >
> >
> >>It's a violation of the Command/Query Separation Principle. According
> >>to the principle, a method should be a command or a query but not both.
> >>If a method has a return value it shouldn't set state.
> >>
> >>It's a principle from Betrand Meyer, and definitely one that needs its
> >>profile raised.
> >>
> >>CQSP is also a specific case of SRP applied to methods.
> >>
> >>
> >>
> >CQSP isn't mentioned by name, but does show up in this refactoring:
> >http://www.refactoring.com/catalog/separateQueryFromModifier.html
> >
> >Are you seeing a need for a Side Effect smell?
> >
> >
> I guess it depends on how it is described. If the description is too
> general, we'd all refactor ourselves to Haskell
>
> I wonder if there is catchier phrase for "unintended side-effect?"

Re: Side Effect

Hello Michael, thanks for your note. On Monday, October 2, 2006, at
3:35:41 PM, you wrote:
> I guess it depends on how it is described. If the description is too
> general, we'd all refactor ourselves to Haskell
> I wonder if there is catchier phrase for "unintended side-effect?"
I was taught that it was bad form for a method, even
/intentionally/, to have a side effect and return a value. At the
time it made sense to me, but it occurs to me that i++ returns a
value and has a side effect, so there must be exceptions. ;->
Ron Jeffries
www.XProgramming.com
The work teaches us. -- Richard Gabriel
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/refactoring/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/refactoring/join
(Yahoo! ID required)

Re: Testing private methods

Phil Goodwin <phil.goodwin <at> gmail.com>
2006-10-02 20:14:25 GMT

> On 10/2/06, michael_coxeter <mco <at> mwdata.dk> wrote:
> > [...] So to make my job easier I moved the private methods into an
> > implementation class, made them public and wrote new tests for
> > these. Anyway the refactoring went well and I am pleased with the
> > result.
> >
On 10/2/06, Keith Ray <keith.ray <at> gmail.com> wrote:
>
> You've rediscovered the "iceberg class" code-smell and its remedy
> "extract class(es)"
>
I agree with Keith. You've more than likely improved your code
significantly and the fact that it feels right to you is a testament
to that.
> > My new tests are somewhat linked to the implementation I chose for
> > the original public method.
> >
> > Are they worth keeping around?
Tests ought to cover the boundaries of potential reuse. Their main job
is to describe how to use the code under test and demonstrate what it
will do under use. Once written their primary costs are the time they
take to run and the friction they cause to refactoring. So if the old
test describes a realistic reuse candidate it's probably worth
keeping. If you know that it's redundant and that fact isn't obvious
then you might want to tag it with a comment in case you want to get
rid if it to facilitate a future refactoring.