Search code examples
ruby-on-rails-3rspecrspec-rails

How do I make sure my controller and model specs are consistent with rspec and rails?


This is maybe more of a philosophical question, but...

As I'm working with rspec and rails, I'm getting more comfortable with using mock objects and stubs to isolate my controller tests from my models, and vice versa.

However, that leaves me with a lingering feeling that not everything is connected properly.

As an example, I might have a spec for a controller like this:

it "passes a list of awesome cheeses to the view" do
  Cheese.should_receive(:awesome).and_return( [ ] ) # one method name
  get 'show'
  assigns[:awesome_cheeses].should_not be_nil
end

And then a spec on my Cheese model like:

it "should return a list of awesome cheeses" do
  Cheese.create!(:name => "American", :is_awesome => false)
  Cheese.create!(:name => "Gouda", :is_awesome => true)
  Cheese.awesome_cheeses.should_not be_nil # different method name!
end

If both those specs pass, my app will still be broken, because the method I stub out in the first spec doesn't have the same name as the one I make sure works in the second.

Now, one answer to this is "you need integration tests", but unless my integration tests are super thorough, I might miss an error like this one.

Is there any automated way to compare the methods I expect to be there in my controller tests, with the methods I actually test for in my model tests?


Solution

  • It now looks like there's an extension to Rspec called rspec-fire which claims to help with this. I haven't tried it yet but wanted to document it here for others.

    I also want to link to this talk, because it has an awesome title: http://www.infoq.com/presentations/integration-tests-scam