Frustrations with rSpec

Posted by sam, Sun Feb 24 22:32:00 UTC 2008

I'm working on the new blog, and I'm having some trouble with rSpec testing controllers and nested routes.

Here's my routes file

ActionController::Routing::Routes.draw do |map|
  map.root :controller => "frontpage"
  map.resources :posts, :has_many => :comments 
end 

And here is some of the controller specs I'm trying to test

require File.dirname(__FILE__) + '/../spec_helper'

describe CommentsController do
  describe "handling GET /posts/1/comments" do

    before(:each) do
      @comment = mock_model(Comment)
      Comment.stub!(:find).and_return(@comment)
      @post = mock_model(Post)
      @post.stub!(:comments)
      @post.comments.stub!(:find).and_return([@comment])
      Post.stub!(:find).and_return(@post)
    end

    def do_get
      get :index, :post_id =>@post.id 
    end

    it "should be successful" do
      do_get
      response.should be_success
    end

    it "should render index template" do
      do_get
      response.should render_template('index')
    end

    it "should find all comments" do
      Comment.should_receive(:find).with(:all).and_return([@comment])
      do_get
    end

    it "should assign the found comments for the view" do
      do_get
      assigns[:comments].should == [@comment]
    end
  end

Here's the controller

class CommentsController < ApplicationController
  # GET /comments
  # GET /comments.xml
  before_filter :load_post

  def index
    @comments = @post.comments.find(:all)

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @comments }
    end
  end
  protected 
  def load_post
    @post = Post.find(params[:post_id])
  end
end

Everything works, except for one spec:

When I try to run the spec on "it should find all comments" I get this error

Mock 'Class' expected :find with (:all) once, but received it 0 times

I don't know what to do. I'm trying to understand what I'm doing. Mocks and Stubs are a big leap of faith for someone who grew up using full blown fixtures. I hope my other specs aren't passing due to dumb luck or something like that.

Should I wait and try to do this in the Stories? Is it useful to to rSpec mocks and stubs for a nested resource?

Any ideas? Fire away in the comments.

BTW, I'm using the great article Rolling on Rails with Rails2.0 from Akita on Rails as a starting point for my new blog.

Thanks for the great article!

Filed Under: | Tags: bdd newblog rspec ruby

Comments

  1. Glenn 04.28.08 / 18PM

    Hey Sam! The problem you're having there is that your expectation is that the Class 'Comment' will receive :find, but in fact what really happens it that the model @post receives :find. Change your spec to read: @post.shouldreceive(:find).with(:all).andreturn([@comment]) and I think you'll have better results. Good luck!

Have your say

A name is required. You may use HTML in your comments.