在Rails 3.1中测试模型mixin

时间:2011-10-01 11:52:44

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

我正在升级到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模型。< / p>

3 个答案:

答案 0 :(得分:2)

这是一个很好的问题,我也在与自己斗争。我倾向于采用不同的解决方案。虽然您的模块旨在包含在继承自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项目中使用相同的方法。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

我设法通过测试:

# 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

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