Testing Validation the DRY Way

UPDATE: Please have a look at valid_attributes

We all know the discussion: should we test simple validation or not ? Here is a great argument for testing even the most simple validation logic.

assert_invalid_attributes User, :login=>[”,nil,’admin’], :email=>[”,nil,’aa’]

Can it get any simpler ?

It goes through all of them and and tests them one by one, giving hepful error messages like:

<User.login> expected to be invalid when set to <admin>

All you need to do is define a @valid_attributes = {:username=>’foo’…} hash in your test setup to test things like ‘password is not username’ and never worry about validations again!

This goes to test/test_helper.rb or spec/spec_helper.rb

  #create a set of invalid attributes
def invalid_attributes search='', replace=''
  @valid_attributes ||= {}
  @valid_attributes[search]=replace unless search.blank?
  @valid_attributes
end

#idea: http://www.railsforum.com/viewtopic.php?id=741
#example: User, :login=>['',nil,'admin'], :email=>['',nil,'aa','@','a@','@a']
def assert_invalid_attributes(model_class, attributes)
  attributes.each_pair do |attribute, value|
    assert_invalid_value model_class, attribute, value
  end
end

#idea: http://www.railsforum.com/viewtopic.php?id=741
#example: User, :login, ['',nil,'admin']
def assert_invalid_value(model_class, attribute, value)
  if value.kind_of? Array
     value.each { |v| assert_invalid_value model_class, attribute, v }
  else
    attributes = invalid_attributes(attribute,value)
    record = model_class.new(attributes)
    assert_block "<#{model_class}.#{attribute}> expected to be invalid when set to <#{value}>" do
      record.valid? # Must be called to generate the errors
      record.errors.invalid? attribute
    end
  end
end

3 thoughts on “Testing Validation the DRY Way

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s