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. 
Implementing the Validator Interface A Validator implementation must contain a constructor, a set of accessor methods for any attributes on the tag, and a validate method, which overrides the validate method of the Validator interface.
Custom validators take the value from the FormControl , where every input acts as a FormControl . So let's create a form along with a validator function. Create a new file called customvalidator. validator.
Use the CustomValidator control to provide a user-defined validation function for an input control. The CustomValidator control is a separate control from the input control it validates, which allows you to control where the validation message is displayed. Validation controls always perform validation on the server.
I am not a huge fan of the other approach because it ties the test too close to the implementation. Also, it's fairly hard to follow. This is the approach I ultimately use. Please keep in mind that this is a gross oversimplification of what my validator actually did... just wanted to demonstrate it more simply. There are definitely optimizations to be made
class OmniauthValidator < ActiveModel::Validator   def validate(record)     if !record.omniauth_provider.nil? && !%w(facebook github).include?(record.omniauth_provider)       record.errors[:omniauth_provider] << 'Invalid omniauth provider'     end   end end   Associated Spec:
require 'spec_helper'  class Validatable   include ActiveModel::Validations   validates_with OmniauthValidator   attr_accessor  :omniauth_provider end  describe OmniauthValidator do   subject { Validatable.new }    context 'without provider' do     it 'is valid' do       expect(subject).to be_valid     end   end    context 'with valid provider' do     it 'is valid' do       subject.stubs(omniauth_provider: 'facebook')        expect(subject).to be_valid     end   end    context 'with unused provider' do     it 'is invalid' do       subject.stubs(omniauth_provider: 'twitter')        expect(subject).not_to be_valid       expect(subject).to have(1).error_on(:omniauth_provider)     end   end end   Basically my approach is to create a fake object "Validatable" so that we can actually test the results on it rather than have expectations for each part of the implementation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With