Activerecord Rails 3和Rspec中的存根链式查询

Activerecord Rails 3和Rspec中的存根链式查询,activerecord,ruby-on-rails-3,rspec,stub,Activerecord,Ruby On Rails 3,Rspec,Stub,我试图测试一个基于其他作用域链的作用域。(“下面的公共_流”) 但是,我仍然收到此错误: Failure/Error: Entry.public_stream(@user) undefined method `includes_values' for #<Entry:0xd7b7c0> 失败/错误:Entry.public\u流(@user) 未定义的方法“包含值”# 似乎includes_values是ActiveRecord::Relation对象的一个实例变量,但当我尝试存

我试图测试一个基于其他作用域链的作用域。(“下面的公共_流”)

但是,我仍然收到此错误:

Failure/Error: Entry.public_stream(@user)
undefined method `includes_values' for #<Entry:0xd7b7c0>
失败/错误:Entry.public\u流(@user)
未定义的方法“包含值”#

似乎includes_values是ActiveRecord::Relation对象的一个实例变量,但当我尝试存根它时,仍然收到相同的错误。我想知道是否有人对stubing Rails 3的新链式查询有经验?我可以找到关于2.x的find hash的一系列讨论,但没有关于如何测试当前内容的任何讨论。

尝试传递Arel,因为它的作用域可能会丢失

it "should use the public, without_user, completed, and limit scopes" do
  @chain = Entry
  @chain.should_receive(:public).and_return(@chain.public)
  @chain.should_receive(:without_user).with(@user).and_return(@chain.without_user(@user))
  @chain.should_receive(:completed).and_return(@chain.completed)
  @chain.should_receive(:limit).with(15).and_return(Factory(:entry))

  Entry.public_stream(@user)
end

为此,我使用rspec的
存根链
。您可能可以使用以下内容:

一些_model.rb

scope :uninteresting, :conditions => ["category = 'bad'"],
                      :order => "created_at DESC"
控制器

@some_models = SomeModel.uninteresting.where(:something_else => true)
规格


首先,您可能不应该测试内置的Rails功能

您应该只为自己编写的代码编写单元测试(如果您练习TDD,这应该是第二天性)——Rails为其构建的功能提供了一套完整的单元测试——复制这一点毫无意义

至于抛出的错误,我认为您的问题在这一行:

@chain.should_receive(:limit).with(15).and_return(Factory(:entry))
您希望链返回一个
工厂
,这实际上是
ActiveRecord
的一个实例,但实际上是这样

因此,您的期望本身是不正确的,并且可能确实导致抛出的错误

请记住,作用域实际上不会返回您期望的记录,除非您显式地迭代它们。此外,关系的记录永远不会返回单个记录。它们总是返回一个空数组或一个带记录的数组。

与上面的答案相同

SomeModel.stub_chain(:uninteresting, :where) {mock_some_model}
Rspec 3版本:

allow(SomeModel).to receive_message_chain(:uninteresting).and_return(SomeModel.where(nil))
参考:


出于好奇,如果您不使用
public
,它是否有效?您的作用域名称与Ruby
public
关键字之间存在冲突。不确定这是否是问题所在,但它会对测试失败的位置感兴趣。作用域与数据库直接相关,因此没有必要单独测试它们。只需创建一些真实记录并测试查询返回的内容。
@chain.should_receive(:limit).with(15).and_return(Factory(:entry))
SomeModel.stub_chain(:uninteresting, :where) {mock_some_model}
allow(SomeModel).to receive_message_chain(:uninteresting).and_return(SomeModel.where(nil))