何时使用RSpec let()?

我倾向于在块之前使用设置实例变量。 然后我在这些例子中使用这些变量。 我最近遇到let() 。 根据RSpec文档,它已经习惯了

...定义一个记忆辅助方法。 该值将在同一个示例中的多个调用中缓存,但不会跨越示例。

这与在前面的块中使用实例变量有什么不同? 还应该什么时候使用let() vs before()


我总是喜欢let一个实例变量出于以下几个原因:

  • 实例变量在引用时会弹出。 这意味着如果你用手指点实例变量的拼写,会创建一个新文件并将其初始化nil ,这会导致细微的错误和误报。 既然let创建了一个方法,当你拼错它时你会得到一个NameError ,我认为这更好。 它也使得重构规格变得更容易。
  • 即使示例没有使用钩子中定义的任何实例变量, before(:each)钩子也会在每个示例之前运行。 这通常不是什么大问题,但如果实例变量的设置需要很长时间,那么你正在浪费周期。 对于由let定义的方法,只有在示例调用初始化代码时才会运行初始化代码。
  • 您可以将示例中的局部变量直接重构为let,而无需更改示例中的引用语法。 如果你重构到一个实例变量,你必须改变你在示例中引用该对象的方式(例如添加一个@ )。
  • 这有点主观,但正如迈克刘易斯指出的那样,我认为它使规格更易于阅读。 我喜欢我的定义所有依赖的对象与组织let ,保持我的it块好和短。

  • 使用实例变量和let()之间的区别在于let()懒惰评估的 。 这意味着let()不会被计算,直到它定义的方法第一次运行。

    beforelet之间的区别在于, let()为您提供了一种以“级联”风格定义一组变量的好方法。 通过这样做,通过简化代码,规范看起来好一点。


    我在我的rspec测试中完全替换了实例变量的所有用法,以使用let()。 我为一个朋友写了一个快速的例子,用它来教一个小型的Rspec类:http://ruby-lambda.blogspot.com/2011/02/agile-rspec-with-let.html

    正如这里的其他一些答案所述,let()是懒惰评估的,所以它只会加载那些需要加载的。 它干燥了规格并使其更具可读性。 实际上,我已经以inherited_resource gem的样式移植了Rspec let()代码以用于我的控制器。 http://ruby-lambda.blogspot.com/2010/06/stealing-let-from-rspec.html

    除了懒惰的评估之外,另一个优势是,结合ActiveSupport :: Concern和规范/支持/行为中的load-everything-in,您可以创建专用于您的应用程序的专用mini-DSL。 我已经编写了一些针对Rack和RESTful资源的测试。

    我使用的策略是Factory-everything(通过Machinist + Forgery / Faker)。 但是,可以将它与before(:each)块结合使用,以便为一整组示例组预加载工厂,从而使规格运行速度更快:http://makandra.com/notes/770-taking-advantage -of-rspec的-S-LET-在前方的块

    链接地址: http://www.djcxy.com/p/59299.html

    上一篇: When to use RSpec let()?

    下一篇: How do I run only specific tests in Rspec?