ruby on rails - एक कस्टम सत्यापनकर्ता का परीक्षण कैसे करें?




ruby-on-rails testing (4)

आधार के रूप में महान उदाहरण का उपयोग करके मैं निम्नलिखित के साथ आया (रेल और आरएसपीईसी 3 के लिए)।

# /spec/lib/slug_validator_spec.rb
require 'rails_helper'

class Validatable
  include ActiveModel::Model
  include ActiveModel::Validations

  attr_accessor :slug

  validates :slug, slug: true
end

RSpec.describe SlugValidator do
  subject { Validatable.new(slug: slug) }

  context 'when the slug is valid' do
    let(:slug) { 'valid' }

    it { is_expected.to be_valid }
  end

  context 'when the slug is less than the minimum allowable length' do
    let(:slug) { 'v' }

    it { is_expected.to_not be_valid }
  end

  context 'when the slug is greater than the maximum allowable length' do
    let(:slug) { 'v' * 64 }

    it { is_expected.to_not be_valid }
  end

  context 'when the slug contains invalid characters' do
    let(:slug) { '*' }

    it { is_expected.to_not be_valid }
  end

  context 'when the slug is a reserved word' do
    let(:slug) { 'blog' }

    it { is_expected.to_not be_valid }
  end
end

मेरे पास निम्नलिखित सत्यापनकर्ता है:

# 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

मैं अपनी lib निर्देशिका के अंदर आरएसपीसी में इसका परीक्षण करने में सक्षम होना चाहता हूं। अब तक समस्या यह है कि मुझे यकीन नहीं है कि EachValidator को कैसे प्रारंभ किया EachValidator


एक और उदाहरण, स्पेस में नई कक्षा बनाने के बजाय ऑब्जेक्ट को विस्तारित करने के साथ। BitcoinAddressValidator यहां एक कस्टम सत्यापनकर्ता है।

require 'rails_helper'

module BitcoinAddressTest
  def self.extended(parent)
    class << parent
      include ActiveModel::Validations
      attr_accessor :address
      validates :address, bitcoin_address: true
    end
  end
end

describe BitcoinAddressValidator do
  subject(:model) { Object.new.extend(BitcoinAddressTest) }

  it 'has invalid bitcoin address' do
    model.address = 'invalid-bitcoin-address'
    expect(model.valid?).to be_falsey
    expect(model.errors[:address].size).to eq(1)
  end

  # ...
end

मैं परीक्षण उद्देश्यों के लिए एक अज्ञात वर्ग बनाने की अनुशंसा करता हूं जैसे कि:

require 'spec_helper'
require 'active_model'
require 'email_validator'

RSpec.describe EmailValidator do
  subject do
    Class.new do
      include ActiveModel::Validations    
      attr_accessor :email
      validates :email, email: true
    end.new
  end

  describe 'empty email addresses' do
    ['', nil].each do |email_address|
      describe "when email address is #{email_address}" do
        it "does not add an error" do
          subject.email = email_address
          subject.validate
          expect(subject.errors[:email]).not_to include 'is not a valid email address'
        end
      end
    end
  end

  describe 'invalid email addresses' do
    ['nope', '@', '[email protected]', '.', ' '].each do |email_address|
      describe "when email address is #{email_address}" do

        it "adds an error" do
          subject.email = email_address
          subject.validate
          expect(subject.errors[:email]).to include 'is not a valid email address'
        end
      end
    end
  end

  describe 'valid email addresses' do
    ['[email protected]', '[email protected]'].each do |email_address|
      describe "when email address is #{email_address}" do
        it "does not add an error" do
          subject.email = email_address
          subject.validate
          expect(subject.errors[:email]).not_to include 'is not a valid email address'
        end
      end
    end
  end
end

यह Validatable जैसे हार्डकोडेड वर्गों को रोक देगा, जिसे कई चश्मे में संदर्भित किया जा सकता है, अप्रत्याशित मान्यताओं के बीच बातचीत के कारण अप्रत्याशित व्यवहार से, जिसे आप अलगाव में परीक्षण करने की कोशिश कर रहे हैं।


यहां एक त्वरित कल्पना है जिसे मैंने उस फ़ाइल के लिए खारिज कर दिया और यह अच्छी तरह से काम करता है। मुझे लगता है कि स्टबिंग शायद साफ हो सकती है, लेकिन उम्मीद है कि यह आपको शुरू करने के लिए पर्याप्त होगा।

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", "[email protected]")
  end

  it "should validate invalid address" do
    @mock.errors[].should_receive('<<')
    @validator.validate_each(@mock, "email", "notvalid")
  end  
end






activemodel