【问题标题】:testing a model mixin in Rails 3.1在 Rails 3.1 中测试模型 mixin
【发布时间】:2011-10-01 11:52:43
【问题描述】:

我正在升级到 Rails 3.1,但在测试我们包含在多个 ActiveRecord 模型中的模块时遇到问题。我们之前使用了一个测试模型,如下所示:

describe FundTransfer do

  class TestFundTransfer < ActiveRecord::Base
    include FundTransfer

    # stub db columns
    class << self
      def columns() FundReturn.columns; end
    end
  end

  subject { TestFundTransfer.new }

  it { should belong_to(:admin) }
  it { should belong_to(:bank_account) }

  it "is not valid without bank account and moneybookers account" do
    fund_transfer = TestFundTransfer.new
    fund_transfer.should_not be_valid
  end

(完整规范:https://gist.github.com/1255960

这会中断,因为它找不到表。我可能会找到一种方法来存根列(就像我们之前所做的那样),但我的问题是:有没有人有经验以更好的方式做到这一点?在这种形式中,我们无法测试任何涉及保存/加载模型的内容。

我正在考虑以下选项:

  • 创建一个污染主架构的表
  • 在事务开始之前在测试中创建一个表
  • 存根列(不允许保存/查找)

有没有人有这方面的经验或有更好的主意?

注意: mixin 指定了belongs_to 关联,因此我不能将ActiveModel 模块用于我的测试模型,它必须是ActiveRecord 模型。

【问题讨论】:

  • 对不起,我不能直接回答你的问题,但你为什么要测试belongs_to?那以及您的验证可能也是rails的关注点,而不是您的关注点。测试你自己的代码,而不是 rails。
  • 也许我没有抓住重点,但 assert_belongs_to 和 co。在我看来总是很愚蠢。
  • 首先,我不认为测试belongs_to 是没有意义的。例如,您可以覆盖 bank_account 方法以接受一些选项,但您的测试将确保它在正常参数下仍然表现良好。此外,最好确保有人不会意外删除这些 rails 调用。其次,我有更多测试,更“原始” :) 完整文件在这里:gist.github.com/1255960
  • 这些都是公平的。我仍然不鼓励使用测试宏自动测试对 rails 方法的调用。在大多数情况下,您只是在添加没有价值的重复内容。

标签: ruby-on-rails ruby-on-rails-3 unit-testing ruby-on-rails-3.1 rspec2


【解决方案1】:

这是一个很好的问题,我自己也一直在努力解决这个问题。我倾向于寻求不同的解决方案。虽然打算将您的模块包含在从 ActiveRecord::Base 继承的类中,但这不是明确的要求。所以我倾向于制造一个可以包含该类的类。

所以是这样的:

  class TestFundTransfer
    cattr_accessor :belongs_to_relations

    def self.belongs_to(relation)
      @@belongs_to_relations ||= []
      @@belongs_to_relations << relation
    end 

    include FundTransfer
  end

  context "on included" do
    it "adds the correct belongs_to relations" do
      TestFundTransfer.belongs_to_relations.should == [:your_relations]
    end
  end

当然这可能会变得复杂,但另一方面它非常明确,并且依赖关系很清楚。 其次,不需要做假魔术来让ActiveRecord::Base 工作。

remarkable_activerecord 内部,我确实看到了一种不同的方法:他们使用辅助方法来创建虚拟表和类(并在使用后删除表)。在他们的情况下,他们需要测试实际的活动记录行为,所以额外的里程真的很有意义。不确定我是否会在 Rails 项目中使用相同的方法。

【讨论】:

    【解决方案2】:

    将类声明为abstract 是否有帮助?

    class TestFundTransfer < ActiveRecord::Base
      include FundTransfer
      def self.abstract_class?; true; end
    end
    

    【讨论】:

    • 不,它仍在寻找表格。
    【解决方案3】:

    我设法通过了测试:

    # stub db columns
    class << self
      def columns() FundReturn.columns; end
      def columns_hash() FundReturn.columns_hash; end
      def column_defaults() FundReturn.column_defaults; end
    end
    

    但我想知道是否有人有更好的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 2018-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多