我不是在测试 Rails 应用程序。只是解决这个问题。
我正在测试一个连接到相对活跃的服务器的库,按时间戳限制记录。这些返回的记录随着时间的推移而变化,使得测试其他限制变得更加复杂。我需要 stub ActiveRecord::where
方法来返回我自己与我创建的对象的自定义关系,以满足我需要的标准。
有点像
relation = double(ActiveRecord::Relation)
relation.stub(:[]).and_return( [MyClass.new(...), MyClass.new(...), ...] )
MyClass.stub(:where).and_return( relation )
是我想要的,但这行不通。我需要它是一个 ActiveRecord::Relation
因为我需要能够调用 ActiveRecord::where
和 ActiveRecord::select
代码中的对象。
编辑 2014-01-28
在 lib/call.rb 中
class Call < ActiveRecord::Base
class << self
def sales start_time, end_time
restricted_records = records(start_time, end_time, :agent_id)
#other code
end
#other methods
private
def records start_time, end_time, *select
# I'm leaving in commented code so you can see why I want the ActiveRecord::Relation object, not an Array
calls = Call.where("ts BETWEEN '#{start_time}' AND '#{end_time}'") #.select(select)
raise calls.inspect
#.to_a.map(&:serializable_hash).map {|record| symbolize(record)}
end
end
end
在 spec/call_spec.rb 中
require 'spec_helper'
require 'call.rb'
describe Call do
let(:period_start) { Time.now - 60 }
let(:period_end) { Time.now }
describe "::sales" do
before do
relation = Call.all
relation.stub(:[]).and_return( [Call.new(queue: "12345")] )
Call.stub(:where).and_return( relation )
end
subject { Call.sales(period_start, period_end) }
it "restricts results to my custom object" do
subject
end
end
end
测试输出:
RuntimeError:
#<ActiveRecord::Relation [ #an array containing all the actual Call records, not my object ]>
最佳答案
ActiveRecord::Relation
是一个类,:[]
是该类的一个实例方法。您正在 stub 类本身的一个方法,因此它不会被任何 Rails 代码调用。
如果您希望 MyClass.where
返回仅包含 :[]
stub 的关系,您必须首先创建一个 Relation 实例,如:
relation = MyClass.all
relation.stub(:[]).and_return( [MyClass.new(...), MyClass.new(...), ...] )
MyClass.stub(:where).and_return( relation )
但是,请注意,为了在此上下文中获取返回的数组,您需要执行以下操作:
MyClass.where("ignored parameters")["ignored parameters"]
此外,如果您随后在 relation
上调用 where
,您将返回 Relation
的新实例它将不再被 stub 。
关于ruby - Stub ActiveRecord::Relation with ActiveRecord 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21344992/