9

似乎有很多支持使用let()in rspec 来初始化变量。在哪些情况下可以使用实例变量(即@name)?

4

2 回答 2

14

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

  • 实例变量在被引用时就存在了,这意味着如果您在实例变量拼写中犯了任何错误,那么当一个新的实例变量被初始化为 nil 时,它肯定会导致您遇到一些问题。但是如果你拼错了,你会得到 NameError 。

  • 此外,您将在 before 块中初始化实例变量,这意味着每次运行规范时都会执行 before 块,即使该规范不使用您已初始化的那些实例变量。下面给出的例子;

    before do
      @user  = Factory :user
      @movie = Factory :movie
    end
    
    it "should have user" do
      @user.should eq User.first
    end
    
    it "should have movie" do
      @movie.should eq Movie.first
    end
    

尽管所有规范都运行良好,但@movie在第一个规范中没有使用,@user在第二个规范中没有使用。

你也可以用 let 和 bang "!" let!,let被延迟评估,如果你不调用它永远不会被实例化,用于let定义 memoized helper ,而let!在每个方法调用之前强制评估。

于 2013-01-02T07:12:17.130 回答
7

我赞成这个问题,但最后我自己回答了这个问题。

首先描述差异

使用该let方法时,它不会初始化变量,直到它在测试中被引用——这使得它不同于从@instance variables一开始就被初始化的变量。

总的来说没有太大的差异。@instance variables当您想确保let对象已初始化时使用。但另一方面,这也可以用 . 来完成let!,因此没有明显的理由使用@instance variable.

总而言之,对我来说,使用 over 有明显的理由,但没有明显的理由使用over@instance variablelet@instance variableslet!

@instance variables需要更多时间来加载,并且使用它们可能会导致代码中不必要的复杂性,这可以通过使用let或来避免let!

你也可以看看这两个答案,也许它会给你更多的信息:

何时使用 RSpec let()?

RSpec:let 和 before 块有什么区别?

于 2013-03-26T13:41:36.493 回答