On Jan 6, 2009, at 1:16 PM, Stephen Eley wrote:
On Tue, Jan 6, 2009 at 10:53 AM, Matt Darby <[email protected]>
wrote:
I'm stumped. How would I go about specing the "update_sandbox"
method?
I couldn't hope to compete with David's answer when it comes to
specifics, but more generally, it occurs to me that your question is a
little imprecise and that could point to part of the cognitive
disconnect. You ask how to spec the method, but you're NOT specing
the "update_sandbox" method in the example you posted. You're specing
a controller's "new" action. Creating a stub or mock for a method
isn't the same as specing it. A spec tests something to see if it
does what it's supposed to. Mocking or stubbing is the opposite:
instead of testing the method, you're pretending the method doesn't
exist and replacing it with a cardboard cutout.
Hi Stephen!
My aim is to spec the Bid::new action; all it really does is call the
#update_sandbox method with a particular block. If I am to test
strictly the behavior of the action, I would really just be testing
the View as it's based on RJS. The View is spec'd, but I need to
simulate the actual updating of the View via the returned Javascript.
Other things I noticed:
1.) There's really no point in putting identical stub!() and
should_receive() declarations in the same example. should_receive()
does everything stub!() does and slightly more. It replaces the
method AND says "Complain if this doesn't get called." When you see
them used in the same spec file, what you're usually seeing is stub!()
in the "before" blocks just to replace external interfaces and make
sure nothing breaks, and then should_receive() in multiple individual
examples to prove that things called when they should.
Good to know! That will really clean up my specs (and save me a ton of
typing!)
2.) On that note, it's becoming more and more the accepted practice to
have only one "should" per example. (Including "should_receives" or
other mocks.) That way, if one of the expectations breaks, you'll
know which one from the "it should..." text and won't have to look at
individual lines.
Agreed, however, I wasn't sure how to approach this case as I'm
testing a method and a block at the same time. By the time I'd arrived
at the spec I originally posted I was well into the "Grasping At
Straws" phase.
3.) You _could_ probably make this spec work as it stands by changing
the "update_sandbox" call to expect a Proc with the "render_to_string
..." block included; that's what actually happens when you call a
method with a "do" block, you're passing it an anonymous Proc as a
parameter. Tweak it enough and I'll bet you could get this to work.
Duly noted.
4.) BUT, I agree with David, there's probably no point. At this level
your spec becomes sort of trivial; you're not even testing behavior
any more, you're testing for the existence of certain lines of code.
Think big picture: WHY are you testing? What is it you want to prove?
Your users don't care whether render_to_string() ever gets called
with certain parameters, and tomorrow you won't care either. You DO
care whether the controller's "new" method responds with an
appropriate block of Javascript when accessed via AJAX. You can find
that out by making the request and checking the response, but if you
stub out the part that actually generates the Javascript, all you'll
learn is "the controller get called and it responded." If that's all
you want to know, you could mock update_sandbox to return "neener
neener" and test for THAT. (And make sure to spec the
update_sandbox() method thoroughly elsewhere.)
I don't necessarily care what #update_sandbox actually produces, I
just want to make sure that it is called with the expected
"render_to_string" call.
Can you clarify "making the request and checking the response"? Is it
possible to just check the "xhr :get, :index" call for a standard hunk
of Javascript? If so, problem solved -- again, I don't yet have a
super firm grip on controller specing when AJAX/RJS is concerned. I'm
eagerly awaiting David's book!
5.) OR... You might gain some good food for thought by going to the
MerbCamp videos (http://merbcamp.com/video) and watching Yehuda Katz's
video on testing (http://merbcamp.com/video/katz1.mp4). Don't worry
about the Merb stuff; what he's describing is a general approach and
it's just as applicable to Rails. The philosophy is somewhat contrary
to the "unit test everything in isolation" philosophy that many others
espouse, but it doesn't hurt to learn both and decide which style
suits you best.
I shall, thanks for the pointer.
I personally found Yehuda's approach to be a slap of cold water and
then a breath of fresh air; since I started it, I've almost entirely
stopped mocking things, and I no longer have the frustrating feeling
that I'm spending 10x longer on tests (and testing my tests, and
debugging my tests) than I am on my application features. But again:
think for yourself, and decide what suits your goals and learning
path.
Thank you for your reply, it was really very insightful and I'm sure
others will learn from it as well!
--
Have Fun,
Steve Eley ([email protected])
ESCAPE POD - The Science Fiction Podcast Magazine
http://www.escapepod.org
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users