Model 如何在RSpec测试中设置模型关联?

Model 如何在RSpec测试中设置模型关联?,model,rspec,associations,Model,Rspec,Associations,我已经在我正在编写的应用程序中为posts/show.html.erb视图编写了规范,作为学习RSpec的一种方法。我还在学习模仿和存根。该问题针对“应列出所有相关注释”规范 我想要的是测试show视图是否显示帖子的评论。但是我不确定的是如何设置这个测试,然后让测试通过should contain('xyz')语句进行迭代。有什么提示吗?其他建议也非常感谢!谢谢 ---编辑 更多信息。在我的视图中,我对注释应用了一个命名的_范围(我知道,在本例中我做得有点倒退),所以@post.comments

我已经在我正在编写的应用程序中为posts/show.html.erb视图编写了规范,作为学习RSpec的一种方法。我还在学习模仿和存根。该问题针对“应列出所有相关注释”规范

我想要的是测试show视图是否显示帖子的评论。但是我不确定的是如何设置这个测试,然后让测试通过should contain('xyz')语句进行迭代。有什么提示吗?其他建议也非常感谢!谢谢

---编辑


更多信息。在我的视图中,我对注释应用了一个命名的_范围(我知道,在本例中我做得有点倒退),所以@post.comments.approved_是(true)。粘贴的代码返回错误“undefined method`approved_is'for#”,这很有意义,因为我告诉它存根注释并返回注释。但是,我仍然不确定如何链接存根,以便@post.comments.approved_is(true)将返回一组注释。

我不确定这是否是最好的解决方案,但我通过只存根指定的_范围,成功地使规范通过。如果有更好的解决方案,我将非常感谢对此的任何反馈和建议

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

读起来有点恶心

你可以这样做:

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
Factory.define :pending_comment, :parent => :comment do |p|
  p.approved = false
end

或者,如果默认值为false,您可以对以下内容执行相同的操作:approved_comments。

这里的方法就是存根

在我看来,控制器和视图规范中的所有对象都应该使用模拟对象来存根。没有必要花时间冗余地测试本应在模型规范中彻底测试的逻辑

下面是一个示例,我将如何在您的粘贴中设置规格

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

我真的很喜欢尼克的方法。我自己也有同样的问题,我能够做到以下几点。我相信mock_模型也会起作用

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