Aug 26 Keeping specs in sync with your model validations
tags:
You have an ActiveRecord model with this long list of required attributes, and it can become a pain keeping your specs in sync with them. Mainly you need to guarantee than required ones are required and not required ones are not. And all that keeping in mind your validations can be dependent of models states. Thanks god, this is ruby and we have shoulda
Let’s see how easy it is:
# app/models/candidate.rb
class Candidate < ActiveRecord::Base
# this is a contextual validation, given the active state
validates_presence_of :name, :if => :active?
# ... and more of them
end
# spec/models/candidate_spec.rb
describe 'active ones' do
it 'should require required attributes' do
# these here must be exactly the same as your model, if not your spec will blow
# because that's what we want, right?
REQUIRED_ATTRS = [:email, :name, :birthday] unless defined?(REQUIRED_ATTRS)
# no attribute is out of this spec
Candidate.new.attribute_names.each do |attr|
#we need a clean state everytime, since shoulda could be changing the object
# this machinist knows how to put object in active state
candidate = Candidate.make_active
# and here the exact instance evaluation of shoulda's macros
if REQUIRED_ATTRS.include? attr.to_sym
candidate.should validate_presence_of(attr)
else
candidate.should_not validate_presence_of(attr)
end
end
end
end
with this artifact, your specs will allways have to be in sync with your models :-)