hello there,how do you tipically spec private methods? The thing is Ï have something like this:def some_methodcomplex_method + other_complex_methodsendprivatedef complex_method...def other_complex_methods ...and the two complex methods can get really tricky to get right, I would like to be able to write specs for them, how do you do that? I mean I cannot do:object.some_private_method
am I?thanks in advance,joaquin
--
www.least-significant-bit.com
_______________________________________________
rspec-users mailing list
rspec...@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
3 is ok.
A "private" method just means it's an implementation detail that is
outside of your API. If you are aiming to test the behavior of your
API, then you don't care about implementation details.
-foca
I disagree that the simple existence of private methods is a sign of a
design flaw. There are plenty of use cases for which private methods
are the simplest and most practical approach. I use them all the time
to help me deconstruct complicated multi-step actions into shorter,
more atomic chunks of logic. They're also how callbacks and filters
are usually implemented in Rails.
That said, though: I usually don't bother testing them. I use RSpec
for unit testing, and when I'm doing that I care about the _external
behavior_ of the unit. I want to know what the object will do when I
poke it from another object. Private methods are an implementation
detail, not a "What does it do?" but rather "How does it do that?" --
and that's not any other class's business.
They're also not usually that complex or brittle. I'll know they work
because the public or protected methods that call them work; and I
don't need tests to understand them. In the exceptional cases where
they _might_ be complex (e.g., some ActiveRecord callbacks or
authentication filters) you're right -- putting them into a module and
testing that module makes sense.
--
Have Fun,
Steve Eley (sfe...@gmail.com)
ESCAPE POD - The Science Fiction Podcast Magazine
http://www.escapepod.org
Yeah, 3 is OK, although ideally you *are* testing the method, albeit
indirectly through the public interface.
Scott
I'm with Scott, this usually indicates a design flaw, and 5 is usually
the solution. The clue is in the names you gave them - you shouldn't
have complex methods, especially private ones.
Can you post any of the code so we can see where the complexity/
problem is?
Ashley
--
http://www.patchspace.co.uk/
http://www.linkedin.com/in/ashleymoran
http://aviewfromafar.net/
> I disagree that the simple existence of private methods is a sign of a
> design flaw. There are plenty of use cases for which private methods
> are the simplest and most practical approach. I use them all the time
> to help me deconstruct complicated multi-step actions into shorter,
> more atomic chunks of logic.
>
> <snip>
>
> They're also not usually that complex or brittle.
I don't think Scott meant to imply that private methods are bad, only
that complex ones private methods are. I use private methods for the
same reason you describe above, to break complex actions down into
more understandable chunks. When it takes 30 private methods before I
can understand the code, that usually indicates there's a problem, and
that a new class needs to emerge. (There are usually other signs of
this too, though.)
Ashley
_______________________________________________
On 14 Oct 2009, at 20:49, Scott Taylor wrote:
On Oct 14, 2009, at 3:36 PM, Joaquin Rivera Padron wrote:
private
def complex_method...
def other_complex_methods ...
and the two complex methods can get really tricky to get right, I would like to be able to write specs for them, how do you do that? I mean I cannot do:
object.some_private_method
You have a few options:
1. Make the method public in the object you are testing
2. Make the method public in the test case
3. Don't test the method
4. Use __send__ or (send) to call it.
5. Refactor private methods to a new object, and make the methods public in that object.
Most of those options suck (esp. 1, 2, 3, & 4) - usually it represents a design flaw (you are doing too much in your class).
I'm with Scott, this usually indicates a design flaw, and 5 is usually the solution. The clue is in the names you gave them - you shouldn't have complex methods, especially private ones.
Can you post any of the code so we can see where the complexity/problem is?
Ashley
--
http://www.patchspace.co.uk/
http://www.linkedin.com/in/ashleymoran
http://aviewfromafar.net/
_______________________________________________
rspec-users mailing list
rspec...@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
> On Oct 14, 2009, at 3:36 PM, Joaquin Rivera Padron wrote:
>
>> hello there,
>> how do you tipically spec private methods? The thing is Ï have
>> something like this:
>
> You have a few options:
>
> 1. Make the method public in the object you are testing
> 2. Make the method public in the test case
> 3. Don't test the method
> 4. Use __send__ or (send) to call it.
> 5. Refactor private methods to a new object, and make the methods
> public in that object.
>
> Most of those options suck (esp. 1, 2, 3, & 4) - usually it
> represents a design flaw (you are doing too much in your class).
Yup. Sprout class[1] works for me, every single time.
[1]http://xunitpatterns.com/Sprout%20Class.html
cheers,
Matt
+447974 430184
ma...@mattwynne.net
http://mattwynne.net
>
> On 14 Oct 2009, at 20:49, Scott Taylor wrote:
>
>> On Oct 14, 2009, at 3:36 PM, Joaquin Rivera Padron wrote:
>>
>>> hello there,
>>> how do you tipically spec private methods? The thing is Ï have
>>> something like this:
>>
>> You have a few options:
>>
>> 1. Make the method public in the object you are testing
>> 2. Make the method public in the test case
>> 3. Don't test the method
>> 4. Use __send__ or (send) to call it.
>> 5. Refactor private methods to a new object, and make the methods
>> public in that object.
>>
>> Most of those options suck (esp. 1, 2, 3, & 4) - usually it
>> represents a design flaw (you are doing too much in your class).
>
> Yup. Sprout class[1] works for me, every single time.
>
> [1]http://xunitpatterns.com/Sprout%20Class.html
By the way, Sprout Class comes from 'Working Effectively with Legacy
Code' (Feathers), which is probably the best book I've read on TDD
(Admittedly I've yet to read The RSpec Book). Highly recommended.
> By the way, Sprout Class comes from 'Working Effectively with Legacy
> Code' (Feathers), which is probably the best book I've read on TDD
> (Admittedly I've yet to read The RSpec Book). Highly recommended.
I've heard good things about this book too. Do you also recommend
xUnit Patterns?
Bizarrely, I'm including xUnit patterns as a reference in a
presentation on mocks I'm giving tomorrow[1], despite never having
read it. (Only because I know it contains some mocking definitions I
refer to...)
Incidentally, the mocking section of the RSpec Book is very good.
Which is to say I agree with what it says :)
Ashley
[1] http://nwrug.org/events/october09/
_______________________________________________
It's been a while since I've read that book. From what I remember it
had a lot of great information, but there were many sections I don't
find applicable for my coding practices. I think a lot of the typical
xUnit styles of testing are heavily influenced from heavier weight
languages (like Java for instance). I think that is reflected in much
of the material in the book.
I did enjoy reading it over a few month period because of the wealth
of information, but I would consider many of the techniques dated
given where the current state of tools (RSpec and Cucumber), the
flexibility of our ruby, and the philosophy of BDD have put us.
So if you're looking to read it for immediately applicable techniques
I would say don't bother, but if you're an information-whore and want
to gain a wealth of knowledge, and want to see a lot of thinking and
techniques that have influenced a lot of today's tools and thinking,
then read it, for sure, but don't expect to read it in a weekened or
even a week... that would be information overload -- your brain would
explode.
Zach
>
> Bizarrely, I'm including xUnit patterns as a reference in a presentation on
> mocks I'm giving tomorrow[1], despite never having read it. (Only because I
> know it contains some mocking definitions I refer to...)
>
> Incidentally, the mocking section of the RSpec Book is very good. Which is
> to say I agree with what it says :)
>
> Ashley
>
> [1] http://nwrug.org/events/october09/
>
> --
> http://www.patchspace.co.uk/
> http://www.linkedin.com/in/ashleymoran
> http://aviewfromafar.net/
>
>
>
>
>
>
>
> _______________________________________________
> rspec-users mailing list
> rspec...@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
--
Zach Dennis
http://www.continuousthinking.com (personal)
http://www.mutuallyhuman.com (hire me)
http://ideafoundry.info/behavior-driven-development (first rate BDD training)
@zachdennis (twitter)
_______________________________________________
rspec-users mailing list
rspec...@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
This is a good point. I was overgeneralizing the response, despite
the question being somewhat more specific. My bad.
(It's a worthwhile discussion, though.)
--
Have Fun,
Steve Eley (sfe...@gmail.com)
ESCAPE POD - The Science Fiction Podcast Magazine
http://www.escapepod.org
Once complexity has been managed, what's the value of that strategy?
--
Have Fun,
Steve Eley (sfe...@gmail.com)
ESCAPE POD - The Science Fiction Podcast Magazine
http://www.escapepod.org
On Thu, Oct 15, 2009 at 3:59 AM, Andrew Premdas <apre...@gmail.com> wrote:Once complexity has been managed, what's the value of that strategy?
>
> You can take this further and state that no public method should ever do
> anything, it should just contain calls to private methods which document how
> the public method works. I expect most would consider that going to far ...
> sigh
Hello, Joaquin.
I typically make these methods public, then test them. I use the
guideline "if it's important enough to test, then it's useful enough
to use somewhere else". I usually end up using the method -- or
something like it -- somewhere else in my code base, then make it
public at that point, anyway.
I have also trusted, for a long time, the idea that if I want to test
it, but it's private, then I really have a small object trying to grow
out of a larger object. I find this especially true when I have three
private methods, all related to each other, in the same class. In that
case I see the clear signal that a smaller object is getting out, so I
let that happen.
Of course, not everyone feels comfortable with so many small objects,
and not everyone feels comfortable making those methods public. If you
don't feel comfortable to do that, then you should look for tricks in
Ruby to let you invoke that private method another way. I think
someone else suggested using __send__() for that. I strongly prefer
not to do that, and when I do, I generally only do it as a first step
towards refactoring the code I'm testing.
Only you can decide what to do, but if you can't decide, then I highly
recommend making the method public, then testing it. If that makes you
dislike the design, then create a new class for the method and move it
there, making it public.
I hope this helps you.
--
J. B. (Joe) Rainsberger :: http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Diaspar Software Services :: http://www.diasparsoftware.com
Author, JUnit Recipes
2005 Gordon Pask Award for contribution to Agile practice :: Agile
2010: Learn. Practice. Explore.
I might shift my focus from whether or not these methods should be
made public or moved to another class and first make sure I had
written examples that focused on the behaviour I was interested in. I
have found that having those tend to be a good help when thinking
about making private methods public. Even if you find you don't need
these methods to be public you will find the examples afford you a
great deal of freedom to refactor that code in a number of ways or by
simply leaving them as private methods all while leaving the examples
intact.
>
> and yeah, I think 5 it my favorite at the moment,
> they don't have to be
> private anyway, also IMHO testing private methods through the public API
> it's not in general applicable (only thinking here, no code sample)...
>
> but anyway I wanted to hear what you guys think about it
Behaviour first. That will help you identify if you're dealing with
different responsibilities which might push you to extract a new
object, or if you're dealing with logic that goes together (in which
you might keep well-named private methods), or if you want to pull out
some of the dry and boring math calculations out into a method on some
utility class.
If you put good examples in place you'll be able to change your mind
later without having to maintain *brittle* specs while having a great
deal of freedom for re-organizing the implementation in a number of
imaginable ways.
--
Zach Dennis
http://www.continuousthinking.com (personal)
http://www.mutuallyhuman.com (hire me)
http://ideafoundry.info/behavior-driven-development (first rate BDD training)
@zachdennis (twitter)
> So if you're looking to read it for immediately applicable techniques
> I would say don't bother, but if you're an information-whore and want
> to gain a wealth of knowledge, and want to see a lot of thinking and
> techniques that have influenced a lot of today's tools and thinking,
> then read it, for sure, but don't expect to read it in a weekened or
> even a week... that would be information overload -- your brain would
> explode.
Thanks for the info. I think I'll look at some other books on my list
first then, and come back to this when I run out.
Cheers
Ashley