Rails和RSpec - 测试关注类方法

Bry*_*yce 22 rspec module ruby-on-rails ruby-on-rails-3

我有以下(简化)Rails关注:

module HasTerms
  extend ActiveSupport::Concern

  module ClassMethods
    def optional_agreement
      # Attributes
      #----------------------------------------------------------------------------
      attr_accessible :agrees_to_terms
    end

    def required_agreement
      # Attributes
      #----------------------------------------------------------------------------
      attr_accessible :agrees_to_terms

      # Validations
      #----------------------------------------------------------------------------
      validates :agrees_to_terms, :acceptance => true, :allow_nil => :false, :on => :create
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

我无法想出在RSpec中测试此模块的好方法 - 如果我只是创建一个虚拟类,当我尝试检查验证是否正常时,我会收到活动记录错误.还有其他人遇到过这个问题吗?

Aar*_*n K 43

查看RSpec 共享示例.

这样你就可以编写以下内容:

# spec/support/has_terms_tests.rb
shared_examples "has terms" do
   # Your tests here
end


# spec/wherever/has_terms_spec.rb
module TestTemps
  class HasTermsDouble
    include ActiveModel::Validations
    include HasTerms
  end
end

describe HasTerms do

  context "when included in a class" do
    subject(:with_terms) { TestTemps::HasTermsDouble.new }

    it_behaves_like "has terms"
  end

end


# spec/model/contract_spec.rb
describe Contract do

  it_behaves_like "has terms"

end
Run Code Online (Sandbox Code Playgroud)


ros*_*sta 6

您可以通过将测试留在包含此模块的类中来隐式地测试模块.或者,您可以在虚拟类中包含其他必需的模块.例如,validatesAR模型中的方法由提供ActiveModel::Validations.所以,对于你的测试:

class DummyClass
  include ActiveModel::Validations
  include HasTerms
end
Run Code Online (Sandbox Code Playgroud)

根据您在HasTerms模块中隐式依赖的依赖关系,可能需要引入其他模块.


Mar*_*ijn 6

我正在努力解决这个问题,并想出以下解决方案,这很像rossta的想法,但使用的是匿名类:

it 'validates terms' do
  dummy_class = Class.new do
    include ActiveModel::Validations
    include HasTerms

    attr_accessor :agrees_to_terms

    def self.model_name
      ActiveModel::Name.new(self, nil, "dummy")
    end
  end

  dummy = dummy_class.new
  dummy.should_not be_valid
end
Run Code Online (Sandbox Code Playgroud)