Rails 3,RSpec 2.5:使用带有命名范围的should_receive或stub_chain

时间:2011-03-09 20:08:49

标签: ruby-on-rails-3 bdd rspec2 arel activemodel

我使用Rails 3.0.4和RSpec 2.5。在我的控制器中,我大量使用命名范围,例如

   @collection = GuestbookEntry.nonreplies.bydate.inclusive.paginate(
       :page => params[:page], :conditions => { ... })

在我的测试中,我希望能够模拟此类查询的结果,而不是措辞。我认为做

之类的事情是不合理的
   GuestbookEntry.stub_chain(:nonreplies, :bydate, ...).and_return(...)

因为在我决定重新排序命名范围时,此测试将失败。

使用Rails 2.3和RSpec 1.x,这很好用:我可以写

   GuestbookEntry.should_receive(:find).with(:all, :conditions => { ... })

并且上述调用将被捕获并正确处理。然而,使用Rails 3,由于某种原因,这不再起作用。

为什么呢?如何在嵌套作用域的结果上设置期望值或存根?由于Rails 3的ActiveModel中的所有内容都是命名范围(感谢ARel),因此必须以某种方式实现,否则测试确实非常脆弱。

谢谢!

更新:另请参阅issue report on GitHub

2 个答案:

答案 0 :(得分:1)

这个问题一直困扰着我!

我认为行为与Rails 2不同的原因是因为在控制器中的变量赋值期间不再执行查询。相反,它根据需要进行了延迟加载。

我同意Mark Wilden的说法,最好将所有这些范围包含在更大的范围内,并在您的模型中对其进行规范。这个范围显然具有特定的功能,因此正如人们会指定调用其他几个方法的方法的行为一样,您将指定连接其他几个范围的范围的行为。

答案 1 :(得分:0)

我会在自己的范围中包含这样一个复杂的查询,并且存根。