2009-08-03 59 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)])