Y a-t-il un moyen de garder une trace des variables créées lors de l'utilisation de Let?
J'ai une série de tests, dont certains utilisent (: serveur) {#blah blah}. Une partie du bla est d'attendre que le serveur démarre de manière à ce qu'il soit dans un état décent avant d'être utilisé. P>
Le problème vient quand j'aurai fini avec ce test. Je veux tuer le serveur à l'aide de serveur.Kill (). Ce serait presque parfait si je pouvais dire quelque chose à l'effet de p> mais cela créerait le serveur et gaspillerait toutes les ressources / temps pour la créer lorsqu'il est référencé, Seulement pour le tuer immédiatement si le serveur n'avait pas été utilisé dans le test précédent. Existe-t-il un moyen de garder une trace de et seulement nettoyer le serveur s'il a été utilisé? P> p>
4 Réponses :
Ce que je ferais, c'est quelque chose comme ceci:
Je pourrais faire quelque chose de similaire, mais au lieu d'avoir le SEAT (: serveur) {} se situer dans le bloc de niveau supérieur, déplacez-le sur le contexte "avec le serveur", supprimez-le avant (chacun) {}, puis le suivant ( : Chaque} {} fonctionnerait ...
@Michaelpapile: Soit Block ne s'appelle qu'une seule fois dans le contexte, le bloc après que le bloc devrait fonctionner très bien.
@Michaelpapile: J'avais des problèmes avec Let () avant et avoir besoin de certains des effets secondaires de Let (), mais pas encore existant, car le SED () qui a provoqué cela n'avait pas encore été référencé. J'ai utilisé une solution de contournement avant que je ne connaissais que je sache! () Dans lequel j'avais un bloc avant (: chaque) qui consistait simplement au nom de l'incroyable let (), ce qui signifie que le contexte de la lettre () s'étend pour inclure l'avant (: Chaque bloc) pour ce test et doit raisonnablement inclure le bloc après (: chacun) également.
Je suis tombé sur un problème similaire. Un moyen simple de résoudre ce problème est de définir une variable d'instance dans la méthode Let de suivre si l'objet a été créé:
describe MyTest do before(:each) { @created_server = false } let(:server) { @created_server = true Server.new } after(:each) { server.kill if @created_server } end
J'aime cette méthode. Merci de le partager. Je l'ai utilisé pour démolir certains modèles qui ont été ajoutés à la DB pendant les tests mais n'ont pas été supprimés après la course au test.
Ceci est sans aucun doute un hack:
describe "cleanup for let" do let(:expensive_object) { ExpensiveObject.new }.cleanup { |v| v.close } end
Écrivez simplement un petit décorateur pour gérer à la fois le démarrage explicite et implicite du serveur et qui vous permet de déterminer si le serveur a été démarré.
Imaginez ceci comme le vrai serveur qui doit être démarré: p> Le décorateur réutilisable pourrait ressembler à ceci: p> Vous pouvez maintenant appliquer cela dans vos spécifications comme ci-dessous: p> Lorsqu'une méthode est appelée sur le décorateur, il fonctionnera sa propre implémentation si l'on existe. Par exemple, si si Vous mettez tout le code posté dans un fichier appelé la sortie sera comme ceci: < / p> Notez que dans les exemples 1 et 2, des méthodes sur le serveur sont appelées et que vous voyez donc la sortie du serveur implicitement démarré par le décorateur. P > Dans l'exemple 3, il n'y a pas d'interaction avec le serveur, par conséquent, vous ne voyez donc pas la sortie du serveur dans le journal. p> à nouveau dans les exemples 4 et 5, il n'y a pas d'interaction directe Avec l'objet serveur dans l'exemple du code, mais le serveur est explicitement démarré via un bloc avant, qui peut également être vu dans la sortie. P> p> #starté? Code> est appelé, il répondra à savoir si le serveur réel a été démarré ou non. S'il n'a pas de mise en œuvre propre de cette méthode, il déléguera l'appel de méthode à l'objet serveur renvoyé par cela. S'il n'a pas de référence à une instance du serveur réel à ce point, il exécutera le
start_procedure fourni fourni pour en obtenir un et en obtenir un et à mémoialiser pour les appels futurs. P>
serveur_spec.rb code> Vous pouvez ensuite l'exécuter avec: p>