ruby-on-railstestingrspecvalidationactivemodel

How to test a custom validator?


I have the following validator:

# Source: http://guides.rubyonrails.org/active_record_validations_callbacks.html#custom-validators
# app/validators/email_validator.rb

class EmailValidator < ActiveModel::EachValidator
  def validate_each(object, attribute, value)
    unless value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
      object.errors[attribute] << (options[:message] || "is not formatted properly") 
    end
  end
end

I would like to be able to test this in RSpec inside of my lib directory. The problem so far is I am not sure how to initialize an EachValidator.


Solution

  • Here's a quick spec I knocked up for that file and it works well. I think the stubbing could probably be cleaned up, but hopefully this will be enough to get you started.

    require 'spec_helper'
    
    describe 'EmailValidator' do
    
      before(:each) do
        @validator = EmailValidator.new({:attributes => {}})
        @mock = mock('model')
        @mock.stub('errors').and_return([])
        @mock.errors.stub('[]').and_return({})
        @mock.errors[].stub('<<')
      end
    
      it 'should validate valid address' do
        @mock.should_not_receive('errors')    
        @validator.validate_each(@mock, 'email', 'test@test.com')
      end
    
      it 'should validate invalid address' do
        @mock.errors[].should_receive('<<')
        @validator.validate_each(@mock, 'email', 'notvalid')
      end  
    end