2009-08-03 91 views
4

我已將pastied規範寫入我正在寫作爲學習RSpec的一種方法的應用程序中的posts/show.html.erb視圖。我仍然在學習模擬和存根。這個問題是特定於「應列出所有相關評論」規範。如何在RSpec測試中設置模型關聯?

我想要的是測試show view顯示帖子的評論。但是我不確定如何設置這個測試,然後讓測試迭代應該包含('xyz')語句。任何提示?其他建議也表示感謝!謝謝。

---編輯

一些更多信息。我有一個named_scope應用於我的視圖中的評論(我知道,在這種情況下,我做了一些倒退),所以@ post.comments.approved_is(true)。代碼粘貼響應與錯誤「未定義的方法`approved_is'爲#」,這是有道理的,因爲我告訴它存根評論並返回一條評論。但是,我仍然不確定如何鏈接存根,以便@ post.comments.approved_is(true)將返回一組註釋。

回答

4

殘樁真的是要走的路。

在我看來,控制器和視圖規範中的所有對象都應該用模擬對象來存根。沒有必要花時間重複測試應該已經在模型規範中進行過徹底測試的邏輯。

這裏有一個例子我將如何建立規範在Pastie ...

describe "posts/show.html.erb" do 

    before(:each) do 
    assigns[:post] = mock_post 
    assigns[:comment] = mock_comment 
    mock_post.stub!(:comments).and_return([mock_comment]) 
    end 

    it "should display the title of the requested post" do 
    render "posts/show.html.erb" 
    response.should contain("This is my title") 
    end 

    # ... 

protected 

    def mock_post 
    @mock_post ||= mock_model(Post, { 
     :title => "This is my title", 
     :body => "This is my body", 
     :comments => [mock_comment] 
     # etc... 
    }) 
    end 

    def mock_comment 
    @mock_comment ||= mock_model(Comment) 
    end 

    def mock_new_comment 
    @mock_new_comment ||= mock_model(Comment, :null_object => true).as_new_record 
    end 

end 
1

我不確定這是否是最好的解決方案,但我設法通過存取named_scope來傳遞規範。我會很感激任何反饋意見,以及建議更好的解決方案,因爲有一個。

it "should list all related comments" do 
@post.stub!(:approved_is).and_return([Factory(:comment, {:body => 'Comment #1', :post_id => @post.id}), 
             Factory(:comment, {:body => 'Comment #2', :post_id => @post.id})]) 
render "posts/show.html.erb" 
response.should contain("Joe User says") 
response.should contain("Comment #1") 
response.should contain("Comment #2") 

0

它讀取有點討厭。

你可以這樣做:

it "shows only approved comments" do 
    comments << (1..3).map { Factory.create(:comment, :approved => true) } 
    pending_comment = Factory.create(:comment, :approved => false) 
    comments << pending_comments 
    @post.approved.should_not include(pending_comment) 
    @post.approved.length.should == 3 
end 

或者其他類似的效果。規範行爲,某些批准的方法應返回批准的帖子。這可能是一個普通的方法或named_scope。等待也會做一些明顯的事情。

你也可以有一個工廠:pending_comment,是這樣的:

Factory.define :pending_comment, :parent => :comment do |p| 
    p.approved = false 
end 

或者,如果錯誤是默認的,你可以做同樣的事情:approved_comments。

0

我真的很喜歡尼克的做法。我自己也有同樣的問題,我可以做到以下幾點。我相信mock_model也會起作用。

post = stub_model(Post) 
assigns[:post] = post 
post.stub!(:comments).and_return([stub_model(Comment)])