RSpec 存根和模拟相关(belongs_to)关系

发布于 2024-10-05 22:24:19 字数 995 浏览 1 评论 0原文

我试图通过尝试扩展使用 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 遇到问题。因为当我在兔子的其中一个视图中引用 clown.name 时,规范就会失败。这个愚蠢的简单应用程序按预期工作,但规格失败,因为我没有阻止(或嘲笑?)小丑从兔子那里正确响应(或者至少我认为正在发生这种情况)?!?我应该如何添加一个存根(或嘲笑与兔子相关的小丑?)。

现存的:

   #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

  ...

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

  ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半仙 2024-10-12 22:24:19

恕我直言(还有其他观点),这不是嘲笑或存根的情况。模拟和存根非常适合外部依赖项(例如 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文