我并不是在测试Rails应用程序。这只是我的交代。
我正在测试一个连接到相对活跃的服务器并通过时间戳限制记录的库。随着时间的推移,返回的记录会发生变化,从而使测试其他限制更加复杂。我需要对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 ]>
MyClass.all
е…ізі»иҖҢдёҚжҳҜжҲ‘зҡ„еӯҳж №е“Қеә”гҖӮжҲ‘еә”иҜҘеӯҳж №дёҚеҗҢзҡ„ж–№жі•еҗ—пјҹ - Brad RiceMyClass.all
ж—¶пјҢдҪ жҢҮзҡ„жҳҜд»Җд№Ҳпјҹ - Peter Alfvinwhere
结果上调用[]
方法,所以你的存根没有生效。如果你在你的规范中说subject['whatever']
,你会得到自定义数组。如果你想让where
本身返回自定义数组,你可以这样做,但那将不是一个关系 - 它将是一个数组。 - Peter Alfvin