I get your point, and I already understood it well before my original
email.  We all know that generic advice isn't always applicable in every
instance, however, and this is a case where the number of distinct specs
required to test all input combinations that are of interest is simply too
large to make it worth doing if I don't use stubs at all.  (yes, even after
all the efficiencies you can get through dynamic spec generation and nested
blocks, which I do in many of my specs).  Stubs are useful in some
circumstances, and this is one of them.  It's obviously hyperbolic and a bit
silly to suggest that stubbing out a public method from one of my models in
order to simplify a spec would lead to stubbing "every method call inside
every method".  You might as well argue that a person should never stub
anything in any spec.

My statement of the refactored methods being public was predicated on the
assumption that I would be stubbing them out (I don't stub private methods),
since there's no other useful reason to refactor in this instance (the code
isn't hard to read, I don't need to reuse any of it elsewhere, and if I
don't stub them out in testing the outer method then refactoring hasn't made
any tests any easier either).

Anyway, if anyone is left reading who hasn't gotten bogged down in this
email chain, and has any other suggestions, please feel free to let me
know.  thanks..



On Tue, Jul 21, 2009 at 2:31 AM, Stephen Eley <sfe...@gmail.com> wrote:

> On Tue, Jul 21, 2009 at 2:05 AM, Barun Singh<baru...@gmail.com> wrote:
> > This isn't a question of refactoring; I can
> > easily refactor the method as you describe but this doesn't resolve the
> > issue (indeed, it just leads to an increased number of public methods in
> the
> > model with no real benefit).
>
> Why would they have to be public?
>
>
> > I can easily spec the find_something and add_something methods so I know
> > that they work correctly.  My question is, how do I write a spec for
> > find_or_add_something in a way where I don't have to re-test the behavior
> of
> > the individual find_something and add_something methods a second time,
> and
> > can just test the overall logic of that method?
>
> My answer for that remains the same: spec it from the outside.  Treat
> it as a black box.  Set up an initial state, then write specs that
> express the expectation that inputs A, B, and C should yield output D.
>  (Where D might be a database record, or a returned value, or both, or
> whatever.)  The number of specs you write in this manner will depend
> on the number of interesting ways that your method could go right or
> wrong.  You may need to provide multiple initial states as well, but
> that's easy in RSpec with nested 'describe' or 'context' blocks.
>
> That the method calls 'add_something' and 'find_something' on the
> inside is immaterial.  You don't have to isolate everything from
> everything else.  If we stubbed every method call inside every method
> we tested, we'd soon get to the point where we were stubbing '+' or
> 'gsub' or 'print.'
>
> Your specs shouldn't have to care how 'find_and_add_something' works.
> What you are expressing is that it DOES work.  Test the inputs and
> outputs, and let it call whatever it wants to get from one to the
> other.
>
>
>
> --
> Have Fun,
>   Steve Eley (sfe...@gmail.com)
>   ESCAPE POD - The Science Fiction Podcast Magazine
>   http://www.escapepod.org
> _______________________________________________
> rspec-users mailing list
> rspec-users@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to