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
精彩评论