我使用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。
答案 0 :(得分:1)
这个问题一直困扰着我!
我认为行为与Rails 2不同的原因是因为在控制器中的变量赋值期间不再执行查询。相反,它根据需要进行了延迟加载。
我同意Mark Wilden的说法,最好将所有这些范围包含在更大的范围内,并在您的模型中对其进行规范。这个范围显然具有特定的功能,因此正如人们会指定调用其他几个方法的方法的行为一样,您将指定连接其他几个范围的范围的行为。
答案 1 :(得分:0)
我会在自己的范围中包含这样一个复杂的查询,并且存根。