Ignorer les rappels sur l'Usine de Fille et Rspec
Je me suis mise à l'essai d'un modèle avec un après avoir créer rappel que je voudrais seulement à certaines occasions, lors des tests. Comment puis-je sauter/courir des rappels à partir de l'usine?
class User < ActiveRecord::Base
after_create :run_something
...
end
Usine:
FactoryGirl.define do
factory :user do
first_name "Luiz"
last_name "Branco"
...
# skip callback
factory :with_run_something do
# run callback
end
end
Vous devez vous connecter pour publier un commentaire.
Je ne suis pas sûr si c'est la meilleure solution, mais j'ai réussi à remplir cette aide:
En cours d'exécution sans rappel:
De course avec rappel:
:on => :create
la validation, l'utilisationafter(:build) { |user| user.class.skip_callback(:validate, :create, :after, :run_something) }
Class.skip_callback
appel sera persistant à travers d'autres tests, donc si vos autres tests attendre le rappel de se produire, ils échoueront si vous essayez d'inverser le saut logique de rappel.after(:build)
bloc. Cela permet à votre usine par défaut à l'exécution de la fonction de rappel et ne nécessite pas la réinitialisation de la fonction de rappel après chaque utilisation.Lorsque vous ne voulez pas exécuter un rappel procédez de la manière suivante:
Être conscient que skip_callback sera persistant sur d'autres caractéristiques après il est exécuté par conséquent considérer la chose comme suit:
Aucune de ces solutions sont bonnes. Ils dégradent les classe par suppression d'une fonctionnalité qui devrait être retiré de l'instance, et non pas à partir de la classe.
Au lieu de la suppression de la fonction de rappel, je suis à la suppression de la fonctionnalité de la fonction de rappel. Dans un sens, j'aime cette approche mieux, car c'est plus explicite.
around_*
(par exempleuser.define_singleton_method(:around_callback_method){|&b| b.call }
).Je tiens à apporter une amélioration à @luizbranco 's réponse à faire after_save rappel plus réutilisables lors de la création d'autres utilisateurs.
En cours d'exécution sans after_save rappel:
En cours d'exécution avec after_save rappel:
Dans mon test, je préfère créer des utilisateurs, sans le rappel par défaut, car les méthodes utilisées exécuter extra stuff je ne suis pas normalement veux dans mes exemples de test.
----------Mise à JOUR------------
J'ai cessé d'utiliser skip_callback parce qu'il y avait certains problèmes d'incohérence dans la suite de test.
Solution Alternative 1 (utilisation de stub et unstub):
Solution Alternative 2 (mon approche préférée):
Cette solution fonctionne pour moi et vous n'avez pas à ajouter un bloc supplémentaire à votre Usine définition:
Un simple stub qui a le mieux fonctionné pour moi dans Rspec 3
User
;:run_something
n'est pas une méthode de classe.Appel skip_callback de mon usine qui s'est avéré problématique pour moi.
Dans mon cas, j'ai une classe de document avec certains s3-rappels associés avant et après créer que je ne veux exécuter lors du test de la pile complète est nécessaire. Sinon, je veux ignorer ceux s3 rappels.
Quand j'ai essayé skip_callbacks dans mon usine, il a persisté que le rappel de sauter, même quand je créé un objet de document directement, sans l'aide d'une usine. Donc, au lieu de cela, j'ai utilisé moka talons dans l'après génération appel et tout fonctionne parfaitement:
before_validation
crochet (en essayant de neskip_callback
avec tout de FactoryGirl debefore
ouafter
options pourbuild
etcreate
ne fonctionne pas)Remarque importante vous devez spécifier à la fois d'entre eux.
Si seulement utiliser avant et d'exécuter de nombreuses spécifications, il va essayer de désactiver le rappel plusieurs fois. Il réussira la première fois, mais sur la seconde, la fonction de rappel n'est pas plus définie. Afin d'erreur
Cela fonctionne avec courant rspec syntaxe (comme de ce post) et est beaucoup plus propre:
Jacques Chevalier réponse sur la façon de sauter before_validation de rappel n'a pas m'aider donc si vous restera en arrière la même chose que moi, ici, est solution de travail:
dans le modèle:
dans l'usine:
Model.skip_callback(...)
Dans mon cas, j'ai le rappel de chargement quelque chose à mon cache redis. Mais alors je n'ai pas/voulez-vous redis une instance en cours d'exécution pour mon environnement de test.
Pour ma situation, similaire à ci-dessus, j'ai juste écrasé mon
load_to_cache
méthode dans mon spec_helper.rb,avec:
Également, dans certaines situations où je veux le tester, j'ai juste à unstub dans la avant le bloc de l'correspondant Rspec cas de test.
Je sais que vous pourriez avoir quelque chose de plus compliqué qui se passe dans votre
after_create
ou risquent de ne pas trouver cela très élégant. Vous pouvez essayer d'annuler le rappel est défini dans votre modèle, par la définition d'unafter_create
crochet dans votre Usine (reportez-vous à factory_girl docs), où vous pouvez sans doute définir le rappel et retourfalse
, en fonction de l'Annulation de rappels " de ce l'article. (Je ne suis pas sûr au sujet de l'ordre dans lequel les rappel sont exécutés, c'est pourquoi je n'ai pas aller pour cette option).Enfin, (désolé, je ne suis pas en mesure de trouver l'article) Ruby vous permet d'utiliser quelques sale méta-programmation de décrocher un rappel crochet (vous devrez le réinitialiser). Je suppose que ce serait la solution la moins souhaitable.
Il y a bien une chose de plus, pas vraiment une solution, mais de voir si vous pouvez obtenir loin avec les réglages d'Usine.construire dans votre cahier des charges, au lieu de la création de l'objet. (Ce serait le plus simple, si vous le pouvez).
Quant à la réponse publiée ci-dessus, https://stackoverflow.com/a/35562805/2001785, vous n'avez pas besoin d'ajouter le code de l'usine. Je l'ai trouvé plus facile de surcharger les méthodes décrites dans les spécifications eux-mêmes. Par exemple, au lieu de (en collaboration avec le code d'usine dans la cité post)
J'aime l'utiliser (sans que l'on cite code usine)
De cette façon, vous n'avez pas besoin de regarder à la fois l'usine et les fichiers de test pour comprendre le comportement de l'épreuve.
Rails 5 -
skip_callback
élever Argument de l'erreur en sautant d'un FactoryBot usine.Il y avait un changement dans les Rails 5 avec comment skip_callback poignées non reconnus, les rappels:
Quand
skip_callback
est appelée à partir de l'usine, le réel de rappel dans le modèle AR n'est pas encore défini.Si vous avez tout essayé et a tiré les cheveux comme moi, voici votre solution (obtenu à partir de la recherche FactoryBot questions) (NOTE le
raise: false
partie):N'hésitez pas à utiliser d'autres stratégies que vous préférez.
J'ai trouvé la solution suivante pour être d'une façon plus propre depuis que le rappel est run/définir un niveau de classe.
Vous pourriez tout simplement le rappel avec un trait pour les cas où vous souhaitez exécuter.