Hi --
Hi --
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Daniel Berger wrote:
[ .. snip .. ]
The advantage of allowing send to access private methods is that it
allows you to test private methods.
Isn't that a Bad Practice (tm)? Private methods are mostly meant for the
internals of a class, and a test should really only test how the class
interacts with the rest of the world - right? (i.e. public methods)
No; you definitely want to test your private methods too.
Conventional wisdom in the Agile/TDD community is that you shouldn't
be testing private methods. The reasoning goes something like this:
1. If you're doing TDD, you're sending messages to objects that other
objects in your system will send. The corresponding methods should be
public.
2. In TDD, private methods appear through refactoring, and therefore
are already tested implicitly through the tests of public methods.
3. When you feel the need to add tests on private methods (which have
appeared through refactoring), it should be considered a sign that a
new object is wanting to be born and should be extracted out into a
new class.
My sense is that some of this thinking is a product of the fact that
testing privates in Java means using reflection, resulting in
refactoring inefficiencies. In Ruby, testing privates is fairly easy
and we don't really have the refactoring tools that the Java community
has, so refactoring in Ruby tends to be much more manual anyhow.
That said, I think the OO design questions that get raised are worthy
of exploration when you feel the need to test something private.
WDYT?
My tendency is to think that the public/private distinction in Ruby
does not overlap very closely with the line between methods you're
likely to use from outside and methods you're not, mainly for two
reasons.
First, private instance methods of Kernel, like raise and sprintf:
these are not behind the black curtain, but are private so as to be
callable in a receiverless way. I'd expect them to be tested.
Second, quick and frequent scope and self-scope changes:
class C
define_method ...
end
etc. define_method, like raise and sprintf, won't go away because of
refactoring; it's a private method, but part of the interface one is
expected to use (rather than simply a by-product of the implementation
of some other such method).
That said, it may be that there are private methods one wouldn't test,
namely those that are really part of the black box, where all you
really need to know is whether the black box produces the right
answer. But I think that's just a subset of private methods,
certainly in core/standard Ruby and quite possibly in other Ruby code.
David
···
On Fri, 3 Aug 2007, David Chelimsky wrote:
On 8/2/07, dblack@rubypal.com <dblack@rubypal.com> wrote:
On Thu, 2 Aug 2007, "Jørgen P. Tjernø" wrote:
--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)