请考虑以下代码:
campaign_spec.rb:
describe Campaign do
before :each do
@campaign = Campaign.new
end
it { should validate_presence_of :position }
end
campaign.rb:
class Campaign < ActiveRecord::Base
attr_accessible :position
validates :position, presence: true
default_scope order(:position)
before_validation :next_position
# sets the position to the next id (1 if none exist) before validation
def next_position
if self.position.blank?
self.position = Campaign.select("coalesce(max(position),0) + 1 as position").reorder(nil).first.position
end
end
end
规范输出:
Failures:
1) Campaign should require position to be set
Failure/Error: it { should validate_presence_of :position }
Expected errors to include "can't be blank" when position is set to nil, got errors: ["name can't be blank (nil)"]
# ./spec/models/campaign_spec.rb:9:in `block (2 levels) in <top (required)>'
从我的模型所说的,我应该能够创建一个Campaign
而不给它一个位置。如果在验证之前不存在,则设置位置。那么为什么我的规格没有通过呢?我在想,也许它不是在调用我的before_validation
方法?
答案 0 :(得分:3)
should validate_presence_of
将属性的值设置为nil,然后运行验证。由于它为零,nil.blank?
返回true
,因此执行回调,将其设置回某个值,因此发现验证不起作用。
事实是,如果您确定它永远不会为空,则无需验证此字段。相反,编写测试以检查在设置为nil时是否确实自动填充。
it 'populates position if blank before validations' do
subject.position = nil
subject.valid?
subject.position.should_not be_nil
end