首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails - RSpec - "let“和"let!”的区别

Rails - RSpec - "let“和"let!”的区别
EN

Stack Overflow用户
提问于 2012-04-16 19:17:08
回答 6查看 26.3K关注 0票数 43

我已经读到了RSpec manual所说的关于不同之处的内容,但有些事情仍然令人困惑。其他的资源,包括“RSpec书”,只解释了"let",而"The Rails 3 Way“和手册一样令人困惑。

我知道"let“只有在被调用时才会被计算,并且在一个作用域中保持相同的值。因此,在manual中的第一个示例中,第一个测试通过,因为"let“只被调用一次,而第二个测试通过,因为它与第一个测试的值相加(在第一个测试中计算过一次,值为1)。

紧随其后的是"let!“在定义时求值,在调用时再次求值,测试应该不会失败,因为"count.should eq(1)“应该是"count.should eq(2)"?

任何帮助都将不胜感激。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-04-16 23:29:52

它不是在定义时调用,而是在每个示例之前调用(然后它被记忆,不会被示例再次调用)。这样,count的值将为1。

不管怎样,如果你有另一个例子,会再次调用之前的钩子--以下所有测试都通过了:

代码语言:javascript
复制
$count = 0
describe "let!" do
  invocation_order = []

  let!(:count) do
    invocation_order << :let!
    $count += 1
  end

  it "calls the helper method in a before hook" do
    invocation_order << :example
    invocation_order.should == [:let!, :example]
    count.should eq(1)
  end

  it "calls the helper method again" do
    count.should eq(2)
  end
end
票数 15
EN

Stack Overflow用户

发布于 2014-07-01 02:23:45

我用一个非常简单的例子理解了letlet!之间的区别。让我先读一读doc语句,然后展示输出。

About let医生说:-

... let是延迟求值的:直到它定义的方法第一次被调用,它才会被求值。

我通过下面的例子理解了其中的区别:

代码语言:javascript
复制
$count = 0
describe "let" do
  let(:count) { $count += 1 }

  it "returns 1" do
    expect($count).to eq(1)
  end
end

让我们现在运行它:

代码语言:javascript
复制
arup@linux-wzza:~/Ruby> rspec spec/test_spec.rb
F

Failures:

  1) let is not cached across examples
     Failure/Error: expect($count).to eq(1)

       expected: 1
            got: 0

       (compared using ==)
     # ./spec/test_spec.rb:8:in `block (2 levels) in <top (required)>'

Finished in 0.00138 seconds (files took 0.13618 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/test_spec.rb:7 # let is not cached across examples
arup@linux-wzza:~/Ruby>

为什么会出现这个错误?因为,正如doc所说,使用let直到它定义的方法第一次被调用时才会被计算。在这个例子中,我们没有调用count,因此$count仍然是0,而不是由1递增。

现在来看let!的部分。医生说

....You可以使用let!在每个示例之前强制调用该方法。这意味着即使你没有在示例中调用helper方法,它仍然会在你的示例运行之前被调用。

让我们也来测试一下:

以下是修改后的代码

代码语言:javascript
复制
$count = 0
describe "let!" do
  let!(:count) { $count += 1 }

  it "returns 1" do
    expect($count).to eq(1)
  end
end

让我们运行这段代码:

代码语言:javascript
复制
arup@linux-wzza:~/Ruby> rspec spec/test_spec.rb
.

Finished in 0.00145 seconds (files took 0.13458 seconds to load)
1 example, 0 failures

看,现在$count返回1,这样测试就通过了。当我使用let!时发生了这种情况,它在示例运行之前运行,尽管我们没有在示例中调用count

这就是letlet!的不同之处。

票数 60
EN

Stack Overflow用户

发布于 2012-04-16 23:25:54

您可以阅读有关此here的更多信息,但基本上。(:let)是延迟计算的,如果您不调用它,它将永远不会被实例化,而(:let!)在每次方法调用之前都会被强制计算。

票数 29
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10173097

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档