2014-09-28 71 views
0

我有一個Company模型與attr_accessor :administrator,所以當用戶創建公司時,他還需要爲該公司的管理員填寫一些字段。我試圖測試,他正確填寫所有字段。RSpec通過驗證測試,應該失敗

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的傳遞。

謝謝!

回答

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 
+0

謝謝,艾哈邁德。這清楚了! – 2014-09-29 18:01:00

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一個struct,然後在對象上調用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