How I learned to stop worrying and love aggressive mockery

Posted by Piers Cawley on Jun 6, 2007

There’s something enormously liberating about writing an RSpec description that starts like:

describe ArticlesController, “feeds:” do
before do
the_mock = mock('everything', :null_object => true)
    ActiveRecord::Base.stub!(:find).and_return(the_mock)
end

it “/articles.atom -> atom feed” do get :index, :format => ‘atom’ response.should render_template(’_atom_feed’) end

… end

The :null_object flag to rspec’s mock function is remarkably potent.The resulting mock will return itself from any method call that hasn’t got some other expectation set up. When I’m testing that my index methods render the appropriate views for the format, I don’t care that all the various variables have been set up correctly - I’ve already tested that in another description - I just want to get to the point where I’m about to render a template.

What this does is decouple my tests. I can change the way that the index method fetches its stuff from the database and I’m only going to have to change the innards of the specs that test that.

I tend to think of this as being analogous to the object oriented pattern of trying to write your methods at a single level of abstraction. Within a given spec, I should only be setting up expectations that are directly related to what I’m testing.