2009/4/24 Stephen Eley <[email protected]> > On Thu, Apr 23, 2009 at 2:19 PM, Fernando Perez <[email protected]> > wrote: > > [...] > > # Assume an article with no comments and a params structure > # have already been set up in before(:each) > > it "should make a new comment belonging to the article" do > post :create, :comment => @my_valid_params > @my_article.should have(1).comment > end > > How clean is that? Now just a couple more specs for *invalid* params > and for where the method directs to, and you're basically done.
Amen to that. > > Mocking and stubbing is starting to get ugly now. > > That much is true. You'll notice I didn't mock or stub anything up > there. I honestly think the controller code by the RSpec scaffold > generator is the wrong approach; it's specing implementation, not > behavior. Even worse, it's specing the implementation details of > *model* code, which shouldn't even be a consideration here. My way > breaks isolation (it hits the database) but it's a lot simpler and > focuses on behavior. And amen to that too. Even within an rspec example I think of each line of code as a Given (setup), When (event) or Then (outcome). Usually when I see a line doing more than one of these - say calling a method and verifying its result - I break it out into separate event and outcome lines. The reason for this is that the givens and outcomes can tinker with whatever they want. They can create mocks, poke around in the database, wire up models, whatever. The event lines though - the Whens - can only interact with the object like client code would. In other words they can't know that an object is a mock, or that a value got into a database because you poked it there. Your example is great. You have an event line that interacts with the controller through a regular HTTP POST, like a client would, and you verify that by checking the database via the ActiveRecord model object. There is no need for a mock here if your example is checking that data ends up in the database (although that does make it more of an integration test than a behavioural spec). Because of rails's evil insistence that a "model" is just a persistence strategy, they are pretty much the same thing. Is it possible to get behavior focus *and* isolation? Yes, but it only has value on a per-line-of-code-in-your-spec basis. Your givens and outcomes shouldn't care about isolation - your events should only be exercising behaviour that is available in the object you are describing. It gets more complicated when a single line of code both exercises behaviour and does verification. I find breaking these out helps my sanity. I started to > think about that. And then I realized, in accordance with the "If > it's hard to spec you're probably doing it wrong" principle, > that...well, Rails is probably doing it wrong. Controllers in Rails > are just doing the Wrong Thing. That's why specing them is so > painful, and why so many of us skip trying. > > What's the right way? I'm still pondering. Me too! > Yeah, I'm a smartass. Well you seem to be on the right lines to me. Cheers, Dan
_______________________________________________ rspec-users mailing list [email protected] http://rubyforge.org/mailman/listinfo/rspec-users
