This goes out to all the veteran Ruby on Rails developers: those who have the RESTful scaffold memorized down to their fingertips; those who can write the tests for it using Cucumber with Webrat, Rails integration tests with Webrat, Rails controller tests with RSpec, Test::Unit, or Shoulda, using mocking, stubbing, test spies, or old-school assertion style:
Stop unit testing the RESTful scaffold
Do write an integration test with Webrat (and Cucumber or Rails integration tests or some crazy script using Hubris), but abstract that out as much as you can. It’s the scaffold. You know it works.
You should write a unit test for your RESTful controller as soon as it deviates, and you should test-drive that deviation both in the integration test and the unit test.
Here, some code. First the #index
action, non-tested:
def index
@posts = Post.all
end
It works. No unit test will uncover a bug in this. The integration test may -
for example, Post
may have no database table yet, or it may not derive from
ActiveRecord::Base
, or may redefine Post.all
, or anything else - but the
unit test for the controller will fail due to a regression.
So now we’ll make a change: posts should be listed alphabetically.
Feature: Posts
# ... existing scenarios that test everything go here ...
Scenario: Viewing posts alphabetically
Given a post exists with a title of "Abe rents storage space"
And a post exists with a title of "Aaron opens his garage to friends"
When I go to the list of posts
Then I should see the posts sorted alphabetically
Make sure that fails. Then add the unit test for the controller; the very first unit test for this controller. Here I’ll use shoulda and jferris-mocha:
require 'test_helper'
class PostsControllerTest < ActionController::TestCase
should "alphabeticalize the blog posts on GET to index" do
Post.stubs(:alphabetical).returns([])
get :index
assert_received(Post, :alphabetical) {|expects| expects.with()}
end
end
That’s all you need because that’s all that has deviated from the RESTful scaffold.
Benefits
- See what deviates from the RESTful scaffold.
- Refactor with ease.
- Spend less time implementing controller unit tests.
The Opposite of Benefits
- Requires your team to know the RESTful scaffold well.
So in summary, do write integration tests all the time, but don’t TATFT. Relax those unit tests.