4

我已经将我为 posts/ show.html.erb视图编写的规范粘贴到我正在编写的应用程序中,作为学习 RSpec 的一种方式。我仍在学习模拟和存根。这个问题特定于“应该列出所有相关评论”规范。

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

- -编辑

更多信息。我有一个 named_scope 应用于我的视图中的评论(我知道,在这种情况下我做了一点倒退),所以@post.comments.approved_is(true)。粘贴的代码以错误“undefined method `approved_is' for #”响应,这是有道理的,因为我告诉它存根注释并返回注释。但是,我仍然不确定如何链接存根,以便 @post.comments.approved_is(true) 将返回一组评论。

4

4 回答 4

4

存根确实是这里的方法。

在我看来,控制器和视图规范中的所有对象都应该使用模拟对象进行存根。没有真正需要花时间冗余测试应该已经在您的模型规范中彻底测试的逻辑。

这是一个示例,我将如何在您的 Pastie 中设置规格……</p>

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
于 2009-08-11T23:17:16.947 回答
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")

结尾

于 2009-08-03T05:50:46.950 回答
0

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

post = stub_model(Post)
assigns[:post] = post
post.stub!(:comments).and_return([stub_model(Comment)])
于 2011-03-18T16:09:30.573 回答
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

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

于 2009-08-04T01:21:50.313 回答