8
votes

Rspec let () nettoyage

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é.

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 xxx

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é?


0 commentaires

4 Réponses :


3
votes

Ce que je ferais, c'est quelque chose comme ceci: xxx


3 commentaires

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.



4
votes

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


1 commentaires

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.



2
votes

Ceci est sans aucun doute un hack:

describe "cleanup for let" do
  let(:expensive_object) {
    ExpensiveObject.new
  }.cleanup { |v|
    v.close
  }
end


0 commentaires

0
votes

É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é: xxx

Le décorateur réutilisable pourrait ressembler à ceci: xxx

Vous pouvez maintenant appliquer cela dans vos spécifications comme ci-dessous: xxx

Lorsqu'une méthode est appelée sur le décorateur, il fonctionnera sa propre implémentation si l'on existe. Par exemple, si #starté? 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.

si Vous mettez tout le code posté dans un fichier appelé serveur_spec.rb Vous pouvez ensuite l'exécuter avec: xxx

la sortie sera comme ceci: < / p> xxx

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.

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.

à 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.


0 commentaires