开发者

RSpec stubs & mocks on related (belongs_to) relationships

I'm trying to get my head around RSpec's 开发者_开发问答incredibly confusing, at least initially, syntax by trying to expand on the default specs that are generated with Rails 3 scaffolding...

I have associated models...very simply:

#clown.rb
class Clown < ActiveRecord::Base
  has_many :rabbits
end

#rabbit.rb
class Rabbit < ActiveRecord::Base
  belongs_to :clown
end

but I'm having trouble with rabbits_controller.spec.rb. In that the specs fail when I reference, say, clown.name in one of rabbit's views. the stupid simple app works as expected but the specs fail because I haven't stubbed (or mocked?) the clown to respond correctly from the rabbit (or at least that's what I think is happening)?!? How should I be adding a stub (or mocking the clown that the rabbit is associate to?).

existing:

   #rabbits.controller.spec.rb
    require 'spec_helper'

    describe RabbitsController do

      def mock_rabbit(stubs={})
        (@mock_rabbit ||= mock_model(Rabbit).as_null_object).tap do |rabbit|
          rabbit.stub(stubs) unless stubs.empty?
        end
      end

      describe "GET index" do
        it "assigns all rabbits as @rabbits" do
          Rabbit.stub(:all) { [mock_rabbit] }
          get :index
          assigns(:rabbits).should eq([mock_rabbit])
        end
      end

  ...


IMHO (and there are other points of view) this isn't a mocking or stubbing situation. Mocks and stubs are great for external dependencies (think web service), but this is internal to your application. What you want is something like factory_girl, which will let you create test data without the headaches of something like fixtures or trying to mock out every dependent relationship, which quickly becomes monotonous. factory_girl has great documentation, but briefly here's what your factories might look like:

Factory.define(:clown) do |f|
  f.rabbits{|c| [c.assocation(:rabbit)]}
  f.name "Pierrot"
end

Factory.define(:rabbit) do |f|
  f.association :clown
end

You'd then use them in your test like so:

describe RabbitsController do 
  describe "GET index" do 
    it "assigns rabbits" do
      @rabbit = Factory(:rabbit)
      get :index
      assigns[:rabbits].should == [@rabbit]      
    end
  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜