The problem isn't your tests...
…the problem is your scaffolding.
A rebuttle to Unpopular Developer 5: Stop Unit Testing Your Scaffold Controllers
Mike Burns of Thoughtbot argues that we should no longer be writing unit tests1 for the default scaffolding for our RESTful controllers.
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.
While the point is well intentioned, I believe he hasn’t delved far enough into why we’ve ended up writing tests for behavior that is this predictable. More to the point, why are we writing predictable behavior at all?
Let’s step back a bit and look at a parallel situation. When we create a new ActiveRecord model, do we test every database querying feature by hand? Do we write explicit tests that show that find(1), find_by_id(1), and find(:all) are working as we expect? We don’t do that because we know that we’re using a very well tested and stable library.
But what if Rails had been designed differently? What if, instead of inheriting from ActiveRecord::Base, we ran a generator that produced all the database access code for us, inline, in our new model? This is clearly a worse situation – we now have the temptation of modifying that code to suite our needs. Did the developer before us use a standard validation, or override #save by hand? Did he remove any of the default functionality?
In this situation, we’d need to test each and every feature generated for us in our unit tests. We’d probably even attempt a misguided extraction that would reduce those tests to a single line, but the tests would still be there.
The root issue in the second scenario isn’t that we have to write repetitive tests for our boilerplate code – It’s that we’ve allowed boilerplate code into our project in the first place. There are better solutions to this problem.
1 Just to clear up any potential confusion here: Rails mistakenly calls the unit tests for your controllers “functional tests”.

Comments
Tammer, I agree completely. We need to build better abstractions in the Ruby world, and especially in Rails.
I have not used any of these better solutions (though Dan has been pushing inherited resources lately), and introducing these solutions to existing code will require long discussions.
That said, we are where we are. These abstractions are still not a part of Rails (or even Suspenders) so we must deal with the RESTful scaffold constantly. Some of us are on teams that know the scaffold far too well; those teams should stop writing tests for it, and we need to do more to educate the community on this to get them up to speed.
There are better tests to write.
I use resource_controller or make_resourceful for exactly this reason. You only have to write the difference between what you need and the “standard” way of doing things. So all you are testing is the hooks you have used. You controller is DRY and so are your tests.
Leave a comment: