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