簡體   English   中英

如何在Rails 4的Model Concern中測試驗證?

[英]How to test validations in a Model Concern in Rails 4?

我有一個Model Concern做驗證:

module UserValidations
  extend ActiveSupport::Concern

  VALID_EMAIL_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i

  included do
  validates :email,
            :presence   => true,
            :format     => VALID_EMAIL_REGEX,
            :uniqueness => { case_sensitive: false }
  end
end

此問題用於多種形式。

現在,我計划針對此問題編寫規范,因此無需以不同的形式規范測試同一組驗證。 但是,我還沒有找到一種很好的方法...

我已經嘗試過類似的事情,但是失敗了...

require 'spec_helper'

class DummyClass
  include ActiveModel::Validations
  include ActiveRecord::Validations
  include UserValidations

  attributes :email, :first_name, :last_name
end

describe "UserValidations" do
  subject { DummyClass.new }

  it { is_expected.to validate_presence_of :email }
end

錯誤堆棧:

/home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/term-ansicolor-1.3.2/lib/term/ansicolor.rb:239:in `term_ansicolor_attributes': wrong number of arguments (3 for 0) (ArgumentError)
  from /home/eyang/grasshopper_dev/gh_user_service/spec/models/concerns/user_validations_spec.rb:8:in `<class:DummyClass>'
  from /home/eyang/grasshopper_dev/gh_user_service/spec/models/concerns/user_validations_spec.rb:3:in `<top (required)>'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/activesupport-4.2.4/lib/active_support/dependencies.rb:268:in `load'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/activesupport-4.2.4/lib/active_support/dependencies.rb:268:in `block in load'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/activesupport-4.2.4/lib/active_support/dependencies.rb:240:in `load_dependency'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/activesupport-4.2.4/lib/active_support/dependencies.rb:268:in `load'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb:1327:in `block in load_spec_files'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb:1325:in `each'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb:1325:in `load_spec_files'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-3.3.2/lib/rspec/core/runner.rb:102:in `setup'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-3.3.2/lib/rspec/core/runner.rb:88:in `run'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-3.3.2/lib/rspec/core/runner.rb:73:in `run'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-3.3.2/lib/rspec/core/runner.rb:41:in `invoke'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/gems/rspec-core-3.3.2/exe/rspec:4:in `<top (required)>'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/bin/rspec:23:in `load'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/bin/rspec:23:in `<main>'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/bin/ruby_executable_hooks:15:in `eval'
  from /home/eyang/.rvm/gems/ruby-2.0.0-p594/bin/ruby_executable_hooks:15:in `<main>'

將關注點包含在虛擬類中會很有幫助。 這個問題並不完全相同,但它演示了該方法:

Rails&RSpec-測試關注類方法

不確定以下測試在Rails應用程序的上下文中的運行情況如何,但是以下是我嘗試盡可能通用地測試您的UserValidations問題。 您應該能夠將代碼復制並粘貼到文件中,然后在其上運行rspec進行測試,然后將其集成到您的項目中(如果它適合您):

require 'active_record'
require 'active_model'
require 'active_support'
require 'shoulda-matchers'

module UserValidations
  extend ActiveSupport::Concern

  VALID_EMAIL_REGEX = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i

  included do
    validates :email,
              :presence   => true,
              :format     => VALID_EMAIL_REGEX,
              :uniqueness => { case_sensitive: false }
  end
end

ActiveRecord::Base.establish_connection(
  adapter: 'sqlite3', database: ':memory:'
)

# Create an 'anonymous' table that has an email field
ActiveRecord::Schema.define do
  create_table :'' do |t|
    t.string :email
  end
end

Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :active_record
    with.library :active_model
  end
end

RSpec.describe UserValidations, type: :model do
  let(:user_validate_able) do
    # Instantiate an anonymous class that inherits from AR::Base
    Class.new(ActiveRecord::Base) do
      include UserValidations

      # ActiveModel needs a model name for error messages,
      # so give one to this anonymous class
      def self.model_name
        ActiveModel::Name.new(self, nil, 'AnonymousModel')
      end
    end.new
  end

  it 'validates presence, uniqueness, and format of email' do
    expect(user_validate_able).to validate_presence_of(:email)
    expect(user_validate_able).to validate_uniqueness_of(:email).case_insensitive
    expect(user_validate_able).to allow_value('guy@incognito.com').for(:email)
  end
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM