Ruby on rails 在无Rails规范的道路上,如何处理深度嵌套模型的测试?

Ruby on rails 在无Rails规范的道路上,如何处理深度嵌套模型的测试?,ruby-on-rails,ruby,ruby-on-rails-3.1,rspec2,Ruby On Rails,Ruby,Ruby On Rails 3.1,Rspec2,在没有Rails规范的情况下,我只看到了仅使用一个模型或最多两个关联的示例。 我想知道如何应用于具有深层嵌套的应用程序。例如,下面是一个嵌套示例 Survey has_many :questions Question has_many :answers Answer belongs_to :user User has_many :surveys has_many :answers 如何编写规范、存根/模拟对象来测试应答模型 我的问题的要点是,我总是在测试嵌套模型的最低

在没有Rails规范的情况下,我只看到了仅使用一个模型或最多两个关联的示例。 我想知道如何应用于具有深层嵌套的应用程序。例如,下面是一个嵌套示例

Survey
  has_many :questions

Question
  has_many :answers

Answer
  belongs_to :user

User
  has_many :surveys
  has_many :answers
如何编写规范、存根/模拟对象来测试应答模型

我的问题的要点是,我总是在测试嵌套模型的最低级别时被抓住。

我的2美分(因为我一直在朝着相同的目标努力):

  • 避免像瘟疫一样违反德墨忒尔法。你的对象越深入到另一个对象的结构中,你需要存根/模拟的对象就越多

  • OpenStruct是你的朋友

  • >P>每当需要从一个深度嵌套的对象中获取数据时,考虑两件事:

  • 在中间的对象上写一个方法,它将返回所需的数据。
  • 创建一个包装关系的对象
我发现Avdi Grimm的Rails上的对象书中的一个模式非常有用:

class YourObject
  def make_related_object
    related_object_maker.call
  end

  def related_object_maker=(maker)
    @related_object_maker = maker
  end

  private
  def related_object_maker
    @related_object_maker ||= RelatedObject.public_method(:new)
  end
end
这使您可以在测试中用lambda替换关系,这非常方便

编辑

describe YourObject do
  let(:maker) { lambda { "some value" } }
  subject { YourObject.new }

  before(:each) do
    subject.related_object_maker = maker
  end

  its(:make_related_object) { should == "some value" }
end
我的2美分(因为我一直在朝着同样的目标努力):

  • 避免像瘟疫一样违反德墨忒尔法。你的对象越深入到另一个对象的结构中,你需要存根/模拟的对象就越多

  • OpenStruct是你的朋友

  • >P>每当需要从一个深度嵌套的对象中获取数据时,考虑两件事:

  • 在中间的对象上写一个方法,它将返回所需的数据。
  • 创建一个包装关系的对象
我发现Avdi Grimm的Rails上的对象书中的一个模式非常有用:

class YourObject
  def make_related_object
    related_object_maker.call
  end

  def related_object_maker=(maker)
    @related_object_maker = maker
  end

  private
  def related_object_maker
    @related_object_maker ||= RelatedObject.public_method(:new)
  end
end
这使您可以在测试中用lambda替换关系,这非常方便

编辑

describe YourObject do
  let(:maker) { lambda { "some value" } }
  subject { YourObject.new }

  before(:each) do
    subject.related_object_maker = maker
  end

  its(:make_related_object) { should == "some value" }
end

哦,我忘了。。。尽可能多地从AR模型中提取业务逻辑。感谢您的回复。你能发布测试示例代码,这样我就可以清楚地知道如何进行lambda调用了吗?哦,我忘了。。。尽可能多地从AR模型中提取业务逻辑。感谢您的回复。你可以发布测试示例代码,这样我就可以清楚地知道如何进行lambda调用了吗?