12

我使用 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),因此这必须以某种方式实现,否则测试确实会非常脆弱。

谢谢!

更新:另见GitHub 上的问题报告

4

2 回答 2

1

这个问题也困扰了我一段时间!

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

我同意 Mark Wilden 的观点,最好将所有这些范围包装在一个更大的范围中,并在您的模型中指定该范围。这个作用域显然有一个特定的功能,所以就像指定一个调用其他几个方法的方法的行为一样,你可以指定一个连接几个其他作用域的作用域的行为。

于 2011-05-21T23:24:49.137 回答
0

我会将如此复杂的查询包装在它自己的范围内,并将其存根。

于 2011-04-23T06:14:09.957 回答