Rspec View specs and integrate_views
We’ve recently had the pleasure of having Craig Ambrose working on a project for us, and as you’d expect when you bring someone new into the team, we’ve been doing some storming. One of the topics that comes up repeatedly within development teams I’m familiar with, including ours, is how fanatically we should adhere to clear separation of unit and integration testing.
I’m fairly laissez faire about the issue. I’m quite happy to write tests for Rails models that actually invoke ActiveRecord and interact with the database. I’ll also happily set up a network of associated objects in the database rather than mock out everything except the class under test, though I do have some ill-defined limit that makes me uncomfortable.
I’m more strict about controller tests – I want the controller itself to be wafer thin, and I’ll generally only test that the controller sets the right instance variables (along with flash notices etc). The tests end up being fairly small, don’t touch the view at all, and I think even the evangelical TDD folk would call them unit tests.
However, Craig rightly points out a couple of problems with this. I’m typically working with server side functionality (if I had to say what I was best out, I’d initially claim domain modelling), so I write crap view code and I rarely write tests for it (someone’s just going to come along and rewrite it to be presentable anyway). It’s a fairly pathetic defence of my laziness, but anecdotally it seems lots of people don’t write view specs. So there’s a whole area of my application that’s not tested very well.
Craig also points out that one of the biggest sources of defects for him is that his controller doesn’t set up what the view expects (or you can express if from the opposite perspective if you prefer) – the failure occurs during the interaction between the controller and the view. These sorts of failures are quite difficult to find with unit tests alone, and probably won’t get picked up by distinct controller specs and view specs.
We could write separate integration specs, but RSpec gives a simple way to catch at least the most egregious of these problems. Unit testing purists might object, but the laissez faire’sts won’t mind. Put “integrate_views” into your descriptions. When integrate_views is specified, RSpec renders the real view rather than mocking out the rendering, and if objects are missing or badly misconfigured you’ll get a rendering exception.
I remembered the integrate_views option from earlier versions of RSpec – it’s not particularly conspicuous in the current version’s documentation, but it can be very useful.






Can you show a short example please?
I finally saw this comment, but only after Marty mentioned it to me (somehow it escaped my email notifications). So….
describe StoriesController,”editing a story” do
integrate_views
before(:each) do
@story = model_factory.story_with_components[:story]
get ‘edit’, :project_id => @story.project.id, :id => @story.id
end
it “should load story” do
assigns[:story].should == @story
end
it “should render edit template” do
response.should render_template(‘edit’)
end
end
hi
i have installed the plugin of rspec and now i have not known to write method in the spec.help me
Thanks
Tim
Tim,
There are some excellent resource on the net that can do a far better job than I can. I suggest you look at the examples on the RSpec site (http://rspec.info/examples.html), or download the Peepcode screencast on RSpec (http://peepcode.com/products/rspec-basics).
Steve
integrate_views can be handy in some situations, but it others it can cause headache and confusion since it requires the controller specs to know a whole lot about everything a view will indirectly need. And at the end of the day the controller spec is managing a spider web of dependencies just so it can render the views.
I know this was written about a year ago a lot has changed since then, but nowadays Cucumber provides an excellent way to ensure all of the pieces are integrated nicely, and you can leave your controller specs in isolation without worrying about not having some level of integration. This isn’t to say that you may not find a time where integrate_views is useful, but Cucumber gives you more meaningful integration than controller specs rendering through to views.
Thanks for sharing Steve, sorry I’m late to the part.