我有一个模型关注点进行验证:
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>'
答案 0 :(得分:0)
将关注点包含在虚拟类中是有帮助的。这个问题并不完全相同,但它证明了这种方法:
答案 1 :(得分:0)
不确定以下测试在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