2015-06-05 73 views
0

我正在讀這本書The Rails 4 Way,我正在學習Rspec。我知道,懶惰評估是在表達使用前不評估的情況,而急切評估則是立即評估表達的情況。 let使用延遲評估,其中在使用let變量之前,塊中的表達式不會被執行。並且let!使用急切的評價。lazy evaluation和rspec的let方法

但是,我仍然對rspec中的letlet!有點困惑。讓我們以下面的例子中,從書:

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,塊不會被執行,所以沒有在那裏創建任何評論。然而,評論會在前面的塊中被評估,所以現在我們有一個評論。然後評論塊將在「添加評論」塊中再次評估,因此將創建兩個評論。既然讓!因此立即進行評估,因此會創建3條評論,而不僅僅是2條評論。

我在這裏誤解了什麼?

回答

0

您正在看到無法使用惰性方法comment的調用。在

然而,評論會偷懶評估塊之前

沒有,你擋在演出前我們已經無關let(:comment)。使用blog_post.comment與Rspec或let不相關。它使用BlogPost模型中定義的方法comment

然後註釋塊將被重新評估在「添加註釋」塊

同樣,沒有,沒有任何調用的comment該塊內。唯一接近的就是blog_post.comments,評論s複數,而不是評論,那就是在你的模型上訪問has_many關係。

調用由let(:comment)定義的comment的唯一方法是用comment。具有相同名稱但屬於不同對象的方法不相關。

+0

如果您沒有像上面說過的那樣調用評論方法,那麼爲什麼作者會說「如果您使用let定義,即使實現可能正在工作,本規範中也只會添加一條評論。讓!我們確保最初的評論被創建並且規範現在會通過(有2條評論)「 – Donato

+0

@Donato因爲你仍然在創建評論,你只是不會通過懶惰的'comment'方法創建它。 'before' block **會創建一個註釋,但它與「...評論將被延遲評估」無關。在任何地方,代碼中的任何地方都會顯示評論,這是作者的觀點。這就是爲什麼你需要'let!' – meagar

+0

@meager在哪裏創建評論?我只在let方法的塊中看到創造。無處。 – Donato