我已经读到了RSpec manual所说的关于不同之处的内容,但有些事情仍然令人困惑。其他的资源,包括“RSpec书”,只解释了"let",而"The Rails 3 Way“和手册一样令人困惑。
我知道"let“只有在被调用时才会被计算,并且在一个作用域中保持相同的值。因此,在manual中的第一个示例中,第一个测试通过,因为"let“只被调用一次,而第二个测试通过,因为它与第一个测试的值相加(在第一个测试中计算过一次,值为1)。
紧随其后的是"let!“在定义时求值,在调用时再次求值,测试应该不会失败,因为"count.should eq(1)“应该是"count.should eq(2)"?
任何帮助都将不胜感激。
发布于 2012-04-16 23:29:52
它不是在定义时调用,而是在每个示例之前调用(然后它被记忆,不会被示例再次调用)。这样,count的值将为1。
不管怎样,如果你有另一个例子,会再次调用之前的钩子--以下所有测试都通过了:
$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发布于 2014-07-01 02:23:45
我用一个非常简单的例子理解了let和let!之间的区别。让我先读一读doc语句,然后展示输出。
About let医生说:-
...
let是延迟求值的:直到它定义的方法第一次被调用,它才会被求值。
我通过下面的例子理解了其中的区别:
$count = 0
describe "let" do
let(:count) { $count += 1 }
it "returns 1" do
expect($count).to eq(1)
end
end让我们现在运行它:
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方法,它仍然会在你的示例运行之前被调用。
让我们也来测试一下:
以下是修改后的代码
$count = 0
describe "let!" do
let!(:count) { $count += 1 }
it "returns 1" do
expect($count).to eq(1)
end
end让我们运行这段代码:
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。
这就是let和let!的不同之处。
发布于 2012-04-16 23:25:54
您可以阅读有关此here的更多信息,但基本上。(:let)是延迟计算的,如果您不调用它,它将永远不会被实例化,而(:let!)在每次方法调用之前都会被强制计算。
https://stackoverflow.com/questions/10173097
复制相似问题