RSpec stubs&模仿相关(belongs_to)关系

时间:2010-12-02 22:27:28

标签: ruby-on-rails rspec rspec2

我试图通过尝试扩展使用Rails 3脚手架生成的默认规范来解决RSpec令人难以置信的混乱,至少在最初的语法...

我有相关的模型......非常简单:

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

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

但是我遇到了rabbits_controller.spec.rb的问题。因为当我在兔子的一个观点中引用小丑。名称时,规格失败了。愚蠢的简单应用程序按预期工作,但规格失败,因为我没有抄(或嘲笑?)小丑从兔子正确回应(或至少这是我认为正在发生的事情)?!?我该如何添加一个存根(或嘲笑兔子所关联的小丑?)。

现有:

   #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

  ...

1 个答案:

答案 0 :(得分:1)

恕我直言(还有其他观点)这不是嘲弄或顽固的情况。模拟和存根非常适合外部依赖(想想Web服务),但这是您的应用程序内部的。你想要的是像factory_girl这样的东西,它可以让你创建测试数据而不会遇到类似夹具之类的麻烦,或者试图模仿每个依赖关系,这很快就会变得单调。 factory_girl有很好的文档,但是这里简要介绍一下你的工厂的样子:

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

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

然后你就可以在测试中使用它们了:

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