我有一个Company
模型attr_accessor :administrator
,因此当用户创建公司时,他还需要为该公司的管理员填写一些字段。我试图测试,他正确填写所有字段。
class Company < ActiveRecord::Base
attr_accessor :administrator
validates :name, presence: true
validates :administrator, presence: true, if: :administrator_is_valid?
private
def administrator_is_valid?
administrator[:name].present? and
administrator[:phone].present? and
administrator[:email].present? and
administrator[:password].present? and
administrator[:password_confirmation].present? and
administrator[:password] == administrator[:password_confirmation]
end
end
company_spec.rb
是:
require 'rails_helper'
describe Company do
it 'is valid with name and administrator' do
company = Company.new(name: 'Company',
administrator: {
name: nil,
email: nil,
phone: nil,
password: 'password',
password_confirmation: ''
})
expect(company).to be_valid
end
end
所以,正如你所看到的,我在验证测试中有很多错误,但是RSpec通过它。
谢谢!
答案 0 :(得分:1)
那是因为您没有正确构建验证。请参阅,if: administrator_is_valid?
将为您的测试返回false,告诉Rails跳过此验证规则。
我建议你使用在线验证器,而不是使用administrator_is_valid?
方法作为验证方法,因为毕竟,如果管理员有效,那么它就存在了。代码应如下所示
validate :administrator_is_valid?
private
def administrator_is_valid?
(administrator[:name].present? and
administrator[:phone].present? and
administrator[:email].present? and
administrator[:password].present? and
administrator[:password_confirmation].present? and
administrator[:password] == administrator[:password_confirmation]) or
errors.add(:administrator, 'is not valid')
end
答案 1 :(得分:1)
您可以像这样清理代码:
validate :administrator_is_valid?
private
def administrator_is_valid?
if administrator_cols_present? && administrator_passwords_match?
true
else
errors.add(:administrator, 'is not valid')
end
end
def administrator_cols_present?
%w(name phone email password password_confirmation).all? do |col|
administrator[col.to_sym].present? # or use %i() instead of to_sym
end
end
def administrator_passwords_match?
administrator[:password] == administrator[:password_confirmation]
end
另一项改进可能是将administrator
移至结构,然后在对象上调用valid?
。
admin = Struct.new(cols) do
def valid?
cols_present? && passwords_match?
end
def cols_present?
cols.values.all? { |col| col.present? }
end
def passwords_match?
cols[:password] == cols[:password_confirmation]
end
end
然后:
validate :administrator_is_valid?
def admin_struct
@admin_struct ||= admin.new(administrator)
end
def administrator_is_valid?
errors.add(:administrator, 'is not valid') unless admin_struct.valid?
end