The*_*dis 39 ruby rspec rspec2
我已经阅读了RSpec手册中关于差异的内容,但有些事情仍然令人困惑.其他所有来源,包括"RSpec Book"仅解释"let",而"The Rails 3 Way"与手册一样令人困惑.
我理解"let"仅在调用时进行评估,并在范围内保持相同的值.所以有意义的是,在手册的第一个例子中,第一个测试通过,因为"let"只调用一次,第二个测试通过,因为它增加了第一个测试的值(在第一个测试中评估了一次)并具有1)的值.
之后,因为"让!" 在定义时进行评估,并在被调用时再次进行,如果测试没有失败,因为"count.should eq(1)"应该是"count.should eq(2)"?
任何帮助,将不胜感激.
Aru*_*hit 45
我理解了一个非常简单的例子let和之间的区别let!.让我先阅读文档句子,然后显示输出动画.
关于让 doc说: -
...
let是惰性求值的:直到第一次调用它定义的方法时才会对它进行求值.
我理解与以下例子的不同之处: -
$count = 0
describe "let" do
let(:count) { $count += 1 }
it "returns 1" do
expect($count).to eq(1)
end
end
Run Code Online (Sandbox Code Playgroud)
让我们现在运行: -
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>
Run Code Online (Sandbox Code Playgroud)
为何错误?因为,如DOC表示,与let,它不是评估在第一次定义了方法被调用,直到.在这个例子中,我们没有调用count,因此$count仍然0没有增加1.
现在来到这一部分let!.医生说
....你可以用let!在每个示例之前强制执行方法的调用.这意味着即使您没有在示例中调用辅助方法,仍然会在示例运行之前调用它.
让我们测试一下: -
这是修改后的代码
$count = 0
describe "let!" do
let!(:count) { $count += 1 }
it "returns 1" do
expect($count).to eq(1)
end
end
Run Code Online (Sandbox Code Playgroud)
让我们运行这段代码: -
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
Run Code Online (Sandbox Code Playgroud)
看,现在$count返回1,因此测试通过了.它发生在我使用的let!,它在示例运行之前运行,尽管我们没有count在我们的示例中调用.
这是如何let和let!互不相同.
dho*_*gen 14
它在定义时不会被调用,而是在每个示例之前调用(然后它被记忆化,而不是由示例再次调用).这样,count的值为1.
无论如何,如果你有另一个例子,再次调用before钩子 - 所有以下测试都通过:
$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
Run Code Online (Sandbox Code Playgroud)
我也认为这令人困惑,但是我认为The Rails 3 Way中的示例很好。
let类似于before块中的实例变量,而let!立即被记住
从Rails 3 Way
describe BlogPost do
let(:blog_post) { BlogPost.create :title => 'Hello' }
let!(:comment) { blog_post.comments.create :text => 'first post' }
describe "#comment" do
before do
blog_post.comment("finally got a first post")
end
it "adds the comment" do
blog_post.comments.count.should == 2
end
end
end
Run Code Online (Sandbox Code Playgroud)
“由于如果使用let定义,因为注释块永远不会对第一个断言执行,因此即使实现可行,在本规范中也只会添加一个注释。通过使用let!我们确保创建了初始注释规格将通过。”