2009-08-03 6 views
4

Ich habe pastied die Spezifikationen, die ich für die Posts/show.html.erb-Ansicht in einer Anwendung geschrieben habe Ich schreibe als Mittel, RSpec zu lernen. Ich lerne immer noch über Mocks und Stubbing. Diese Frage bezieht sich speziell auf die Spezifikation "sollte alle zugehörigen Kommentare auflisten".Wie richte ich Modellassoziationen in einem RSpec-Test ein?

Ich möchte testen, dass die Show-Ansicht die Kommentare eines Beitrags anzeigt. Aber was ich nicht sicher bin, ist, wie man diesen Test einrichtet und dann den Test durchlaufen lassen sollte ('xyz') Anweisungen enthalten sollte. Irgendwelche Hinweise? Andere Vorschläge werden auch geschätzt! Vielen Dank.

--- Bearbeiten

Weitere Informationen. Ich habe ein named_scope auf Kommentare in meiner Ansicht angewendet (ich weiß, ich habe das in diesem Fall ein bisschen zurück getan), also @ post.comments.approved_is (true). Der Code pastiert antwortet mit dem Fehler "undefined Methode` approved_is 'für # ", was sinnvoll ist, da ich ihm Stub-Kommentare erzählt habe und einen Kommentar zurückgebe. Ich bin mir aber immer noch nicht sicher, wie ich die Stubs so verketten soll, dass @ post.comments.approved_is (true) ein Array von Kommentaren zurückgibt.

Antwort

4

Stubbing ist wirklich der Weg, um hier zu gehen.

Meiner Meinung nach sollten alle Objekte in Controller und View-Spezifikationen mit Mock-Objekten stubbed sein. Es besteht keine Notwendigkeit, redundante Logik zu testen, die bereits ausführlich in Ihren Modellspezifikationen getestet werden sollte.

Hier ist ein Beispiel, wie ich die Angaben in Ihrem Pastie einrichten würde ...

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

Ich bin mir nicht sicher, ob dies die beste Lösung ist, aber ich habe es geschafft, die Spezifikation zu übergeben, indem ich nur das named_scope stubbing. Ich würde mich über jede Rückmeldung und Vorschläge für eine bessere Lösung freuen, wenn es eine gibt.

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") 

Ende

0

Es liest ein bisschen böse.

Man könnte so etwas wie tun:

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 

Oder etwas in diesem Sinne. Spezifizieren Sie das Verhalten. Einige genehmigte Methoden sollten genehmigte Kommentare für einen Beitrag zurückgeben. Das könnte eine einfache Methode oder ein named_scope sein. Und pending würde auch etwas Offensichtliches tun.

könnten Sie haben auch eine Fabrik für: pending_comment, so etwas wie:

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

Oder, wenn falsch die Standardeinstellung ist, könnten Sie die gleiche Sache für tun: approved_comments.

0

Ich mag Nicks Ansatz. Ich hatte das selbe Problem und konnte folgendes machen. Ich glaube, mock_model würde auch funktionieren.

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