Я не большой поклонник другого подхода, потому что он слишком тесно связывает тест с реализацией.Кроме того, это довольно трудно следовать.Это подход, который я в конечном итоге использую.Пожалуйста, имейте в виду, что это грубое упрощение того, что на самом деле сделал мой валидатор ... просто хотел продемонстрировать это проще.Определенно необходимо выполнить оптимизацию
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
Связанные спецификации:
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
В основном мой подход заключается в создании поддельного объекта "Validatable", чтобы мы могли фактически проверить результаты на нема не иметь ожидания для каждой части реализации