Specs on private methods

How does a person test private methods?

Is there a way to declare them as private, but retain any tests that
were written during the initial development?

Thanks.

On 8 Jan 2008, at 18:39, Chris O. wrote:

How does a person test private methods?

Is there a way to declare them as private, but retain any tests that
were written during the initial development?

I’m rather liking Jay Field’s approach (described at http://
Jay Fields' Thoughts: Ruby: Testing Private Methods)

In which he basically redeclares the private methods public for the
duration of the test only, with a bit of block-scoped evaling goodness.

Matt


Matt P. | Design & Code
| http://www.reprocessed.org/

Might be a personal thing, but my approach is that I try to test the
public behaviour of the object. Testing private methods is, imho,
getting dangerously close to specifying how the object does its
business, rather than what it does.

I would just spec the externally visible behaviour, where it occurs,
and let the object implement it as it wants (using private methods or
any other mechanism).

Daniel

Chris O. wrote:

How does a person test private methods?

Is there a way to declare them as private, but retain any tests that
were written during the initial development?

Thanks.

When I need to do this I just use the send method.

-Ben

On 8 Jan 2008, at 19:14, Daniel T. wrote:

Might be a personal thing, but my approach is that I try to test the
public behaviour of the object. Testing private methods is, imho,
getting dangerously close to specifying how the object does its
business, rather than what it does.

If you’re a proponent of many-skinny-methods then you wind up with a
lot of public methods which should never need to be called by another
object, so making them private can be a good thing for general users
of the object.

I would just spec the externally visible behaviour, where it occurs,
and let the object implement it as it wants (using private methods or
any other mechanism).

If the object were to implement it itself, that would be great :wink:
Unfortunately, I have to implement the innards, and I’m rubbish so I
like to test things…

Matt


Matt P. | Design & Code
| http://www.reprocessed.org/

On Jan 8, 2008, at 2:20 PM, Ben M. wrote:

Chris O. wrote:

How does a person test private methods?

Is there a way to declare them as private, but retain any tests that
were written during the initial development?

Thanks.

When I need to do this I just use the send method.

But it will break in 1.9 and on! (That’s why Jay Fields didn’t do it
in his post).

Scott

Doesn’t 1.9 allow you to call obj.send!, which will allow you to
access private methods?

Tim

Yes. eigenclass.org

Will obj.send(:method) work in 1.9 or is it saying that the send call
requires 2 params, the method and the object reference?

On Jan 8, 2008 2:47 PM, Chris O. [email protected] wrote:

Will obj.send(:method) work in 1.9 or is it saying that the send call
requires 2 params, the method and the object reference?

In 1.9 you can say obj.send!(:method) even if :method is private.
obj.send(:method) will not work for private methods.

Well there we go, Ben’s method still stands :slight_smile:

Tim

On Jan 8, 2008 1:25 PM, Matt P. [email protected]
wrote:

lot of public methods which should never need to be called by another
object, so making them private can be a good thing for general users
of the object.

Keep in mind that if you’re specifying object behaviour with the
prescribed granular red/green/refactor cycle, then the examples are
all against public methods. Private methods should only ever appear as
a result of refactoring. Those are the many-skinny that you are
talking about.

I would just spec the externally visible behaviour, where it occurs,
and let the object implement it as it wants (using private methods or
any other mechanism).

If the object were to implement it itself, that would be great :wink:
Unfortunately, I have to implement the innards, and I’m rubbish so I
like to test things…

You should check out the bowling kata
(ArticleS.UncleBob.TheBowlingGameKata) if you
haven’t. At the end there are just a few tests and they all touch only
2 public methods, but there are many, many smaller methods that appear
through refactoring. They are all thoroughly tested, though not
directly.

Cheers,
David

obj.send(:method) will work for non-private methods and send! works for
private methods.

additionally there is send() without a receiving object. that is the
only of those methods requiring two parameters.

Chris O. schrieb:

The send call never expects an object reference as a parameter. Either
it is called on an object or without an object context (i.e. kernel). In
the first case the parameter should contain one of the receiving
object’s methods. In the second case the parameter is a kernel method.

But… that’s not really an RSpec topic anymore.

Chris O. schrieb:

I totally agree with you, David!

For quite a while I was testing all my methods (even had to declare them
protected/package scope in java!), but I realized that I was getting
into a
lot of trouble. Now I’ve shifted to testing functionality in stead of
methods.

Now, sometimes you might end up having small methods (typically a result
of
refactoring) that are being used by several clients. In that case you
should
start testing those methods, since they actually represent real business
logic.
I talked to uncle Bob about this issue just a few months ago, and as far
as
I understood, he uses a similar approach.

I think it might make sense to think of the facade pattern when you do
your
testing - do you really care what happens behind the facade?

Stefan

2008/1/9, David C. [email protected]:

Just to clarify, this is what I meant in my original email :slight_smile: Most
of my methods are very small - in Ruby any method longer than 5 lines
is, imho, a code smell that’s waiting to be fixed. However, no matter
how many methods are used to implement the functionality, I test the
public behaviour of the object rather than the methods themselves.
Sometimes, this maps directly to a public method. Sometimes, a spec
will actually use several public methods in concert. With this
approach, I never spec private methods.

Daniel

Well, I think it all depends on the scenario - but in a lot of cases it
should absolutely be considered a code-smell.

Stefan

2008/1/9, Kerry B. [email protected]:

On Jan 9, 2008 10:01 AM, Stefan Magnus Landrø [email protected]
wrote:

logic.
I wonder whether that is a smell indicating that the functionality in
those methods really belongs in its own class?

Kerry

On Jan 9, 2008 6:09 AM, Kerry B. [email protected] wrote:

On Jan 9, 2008 10:01 AM, Stefan Magnus Landrø [email protected] wrote:

I totally agree with you, David!

Then you agree with the majority of the TDD community.

For quite a while I was testing all my methods (even had to declare them
protected/package scope in java!), but I realized that I was getting into a
lot of trouble. Now I’ve shifted to testing functionality in stead of
methods.

Now, sometimes you might end up having small methods (typically a result of
refactoring) that are being used by several clients. In that case you should
start testing those methods, since they actually represent real business
logic.

Again, if they appear through refactoring, then they ARE tested
through the public methods. The only time I would test them directly
would be in the process of trying to locate the source of a bug, or if
I wanted to move the method to another class because it represented a
fundamentally different concept from the one represented by its
current class.

This is all TDD 101 stuff. Maybe we should have required reading on
this list :wink: Here are a few suggestions:

These sorts of questions are explored in great detail in these books.

Cheers,
David

On Jan 9, 2008 7:12 AM, Stefan Magnus Landrø [email protected]
wrote:

lot of trouble. Now I’ve shifted to testing functionality in stead of
those methods really belongs in its own class?
Well, I think it all depends on the scenario - but in a lot of cases it
should absolutely be considered a code-smell.

Keep in mind that a code smell is an indicator, but not a dictator. It
is supposed to draw your attention but you still have to consider the
pros and cons and make a reasoned decision.

Cheers,
David