468 votes

Quand utiliser rspec let ()?

J'ai tendance à utiliser avant de blocs et de définir les variables d'instance et puis les utiliser sur mes exemples, mais récemment je suis tombé sur let(). Selon rspec docs, il est utilisé pour

... de définir un memoized méthode d'assistance. La valeur va être mis en cache à travers de multiples appels dans le même exemple, mais pas à travers des exemples.

Ma question est comment est-ce différent à l'aide de variables d'instance en avant des blocs? Et aussi quand devez-vous utiliser let() vs before()?

617voto

Myron Marston Points 8940

J'ai toujours préféré let à une variable d'instance pour un couple de raisons:

  • Les variables d'Instance de printemps dans l'existence lorsqu'il est référencé. Cela signifie que si vous avez la graisse du doigt l'orthographe du nom de la variable d'instance, un nouveau sera créé et initialisé à l' nil, ce qui peut conduire à des bogues et des faux positifs. Depuis let crée une méthode, vous aurez un NameError quand vous avez mal orthographié, ce qui je trouve préférable. Il est plus facile de refactoriser spécifications, trop.
  • Un before(:each) crochet avant chaque exemple, même si l'exemple n'utilise pas du tout de l'instance des variables définies dans le crochet. Ce n'est pas une grosse affaire, mais si l'installation de l'instance de la variable prend beaucoup de temps, alors vous perdez cycles. Pour la méthode définie par let, le code d'initialisation ne fonctionne que si l'exemple des appels.
  • Vous pouvez restructurer à partir d'une variable locale dans un exemple directement dans un laisser sans changer la le référencement de syntaxe dans l'exemple. Si vous refactoriser à une variable d'instance, vous devez changer comment vous faites référence à l'objet dans l'exemple (par exemple, ajouter un @).
  • C'est un peu subjectif, mais comme Mike Lewis a souligné, je pense qu'il est la spécification la plus facile à lire. J'aime l'organisation de la définition de tous mes objets dépendants avec let et de garder ma it bloc de nice et court.

86voto

Mike Lewis Points 29305

La différence entre l’utilisation de variables d’instances et de let(), c’est que let() est paresseux-évaluée. Cela signifie que let() n’est pas évaluée jusqu'à ce que la méthode qu’il définit est exécutée pour la première fois.

La différence entre avant et laissez est que let() vous donne une belle façon de définir un groupe de variables dans un style « en cascade ». Ce faisant, la spec semble un peu mieux en simplifiant le code.

18voto

Ho-Sheng Hsiao Points 459

J'ai complètement remplacé toutes les utilisations de variables d'instance dans mes tests rspec d'utiliser let(). J'ai écrit un quickie exemple pour un ami qui l'a utilisé pour enseigner à un petit Rspec classe: http://ruby-lambda.blogspot.com/2011/02/agile-rspec-with-let.html

Comme certains des autres réponses ici dit, nous allons() est paresseux évalué de sorte qu'il ne charge que ceux qui exigent le chargement. Elle Sèche jusqu'à la spécification et la rendre plus lisible. J'ai en fait porté le Rspec let() code pour l'utiliser dans mes contrôleurs, dans le style de inherited_resource gem. http://ruby-lambda.blogspot.com/2010/06/stealing-let-from-rspec.html

Le long de avec d'évaluation différée, l'autre avantage est que, combiné avec ActiveSupport::Inquiétude, et de la charge-tout-en spec/support/ comportement, vous pouvez créer votre propre spec mini-DSL spécifiques à votre application. J'ai écrit pour les tests contre Rack de repos et de ressources.

La stratégie que j'utilise est l'Usine-tout (via Machiniste+Faux/Faker). Toutefois, il est possible de l'utiliser en combinaison avec before(:each) blocs de précharger des usines pour toute une série d'exemple de groupes, ce qui permet les spécifications pour courir plus vite: http://makandra.com/notes/770-taking-advantage-of-rspec-s-let-in-before-blocks

13voto

pisaruk Points 483

Il est important de garder à l’esprit que laisser est paresseux évalué et ne mettant pas effet secondaire méthodes dedans sinon vous ne serait pas en mesure de changer de laisser à before(:each) facilement. Vous pouvez utiliser laisser ! au lieu de laisser donc qu’elle est évaluée avant chaque scénario.

9voto

Jon Kern Points 796

En général, let() est plus agréable de syntaxe, et il vous permet d'économiser de frappe @name symboles de tous sur la place. Mais, caveat emptor! J'ai trouvé let() introduit également des bogues (ou au moins se gratter la tête) parce que la variable n'existe pas vraiment jusqu'à ce que vous essayez de l'utiliser... signe révélateur: si l'ajout d'un puts après l' let() de voir que la variable est correcte permet une spécification de passer, mais sans l' puts le spec échoue -- vous avez trouvé cette subtilité.

J'ai aussi constaté que let() ne semble pas cache en toutes circonstances! Je l'ai écrit dans mon blog: http://technicaldebt.com/?p=1242

Peut-être que c'est juste moi?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X