Comment faire pour tester un validateur personnalisé?
J'ai le texte suivant 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
Je voudrais être en mesure de tester cela dans RSpec à l'intérieur de mon répertoire lib. Le problème jusqu'à présent est que je ne suis pas sûr de savoir comment initialiser un EachValidator
.
Vous devez vous connecter pour publier un commentaire.
Voici un rapide spec j'ai frappé vers le haut de ce fichier et ça fonctionne bien. Je pense que le buter pourrait probablement être nettoyé, mais j'espère que ce sera assez pour vous obtenir a commencé.
@validator = EmailValidator.new({:attributes => { :foo => :bar }})
fera l'affaire.Je ne suis pas un grand fan de l'autre approche, car il relie le test de trop près à la mise en œuvre. Aussi, il est assez dur à suivre. C'est l'approche que j'ai finalement utiliser. Veuillez garder à l'esprit que c'est une simplification grossière de ce que mon validateur fait... voulais juste démontrer de manière plus simple. Il y a certainement des optimisations pour être fait
Associés Spec:
Fondamentalement, mon approche est de créer un faux objet "traitement pouvant être validé", de sorte que nous pouvons vraiment tester les résultats plutôt que d'avoir des attentes pour chaque partie de la mise en œuvre
validates_with OmniauthValidator, attributes: 'omniauth_provider'
validates :omniauth_provider, omniauth: true
Je recommande la création d'une classe anonyme à des fins de test, tels que:
Cela permettra d'éviter codé en dur classes telles que
Validatable
, qui pourrait être référencé dans plusieurs spécialisations, résultant dans l'inattendu et difficile à déboguer comportement en raison des interactions entre les indépendants, les validations, que vous êtes en train de tester, dans l'isolement.À l'aide de Neals excellent exemple comme base je suis venu avec la suivante (pour les Rails et les RSpec 3).
ActiveModel::Model
, aussi il peut être préférable de créer une classe anonyme commesubject { Class.new { include ActiveModel::Validations; attr_accessor :slug; validate :slug, slug: true }.new }
Un exemple de plus, avec l'extension d'un objet au lieu de créer de nouvelles classes dans les spécifications. BitcoinAddressValidator est un validateur personnalisé ici.