我正在阅读The Rails 4 Way这本书,我正在学习Rspec。我知道延迟评估是指表达式在使用之前不进行评估,而急切评估是表达式立即评估的地方。 let
使用延迟求值,其中块的表达式在使用let变量之前不会执行。 let!
使用了热切的评估。
但是,我仍然对rspec中的let
和let!
感到有些困惑。我们来自下面的例子:
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
expect(blog_post.comments.count).to eq(2)
end
end
end
作者说:
由于注释块永远不会被执行 断言如果使用了let定义,则只有一个注释 已添加到此规范中,即使实现可能正在运行。 通过使用让!我们确保创建初始评论和规范 现在将通过。
我认为,使用let,会创建两个注释,并且使用let!,会创建三个注释。为什么?因为使用let,块不会被执行,所以没有在那里创建注释。但是,注释将在之前的块中进行延迟评估,所以现在我们有一个注释。然后将在“添加注释”块中再次评估注释块,因此将创建两个注释。自从!立即评估,因此将创建3条评论,而不仅仅是两条评论。
我在这里误解了什么?
答案 0 :(得分:0)
您看到了懒惰comment
方法的调用,但没有。
但是,评论将在前一栏
中进行延迟评估
不,您向我们展示的前一栏与let(:comment)
无关。
使用blog_post.comment
与Rspec或let
无关。它使用的是comment
模型中定义的BlogPost
方法。
然后将在&#34中再次评估评论块;添加评论"块
同样,不,在该块中没有comment
的任何调用。唯一关闭的是blog_post.comments
,评论 s 复数,而不是评论,这样就可以访问模型上的has_many
关系。
调用comment
定义的let(:comment)
的唯一方法是使用单词comment
。具有相同名称但属于不同对象的方法并不相关。