2014-01-25 164 views
5

我沒有測試Rails應用程序。只要把它弄明白就行。存根ActiveRecord ::與ActiveRecord對象的關係

我正在測試一個連接到相對活躍的服務器的庫,通過時間戳限制記錄。這些返回的記錄隨着時間​​的推移而變化,使得測試其他限制更加複雜。我需要將ActiveRecord::where方法與我創建的對象返回自己的自定義關係以滿足我需要的條件。

喜歡的東西

relation = double(ActiveRecord::Relation) 
relation.stub(:[]).and_return([MyClass.new(...), MyClass.new(...), ...]) 
MyClass.stub(:where).and_return(relation) 

是想我,但不起作用。我需要它是一個ActiveRecord::Relation,因爲我需要能夠在代碼中的對象上調用ActiveRecord::whereActiveRecord::select


編輯2014年1月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 

在投機/ 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 ]> 

回答

3

ActiveRecord::Relation是一類,:[]是該類的實例方法。你正在爲類的方法存根,所以它不會被任何Rails代碼調用。

如果你想MyClass.where返回與剛剛:[]存根的關係,你必須先創建一個關係實例,如:

relation = MyClass.all 
relation.stub(:[]).and_return([MyClass.new(...), MyClass.new(...), ...]) 
MyClass.stub(:where).and_return(relation) 

但是,請注意,爲了讓您的回數組在這種情況下,你需要做的:

MyClass.where("ignored parameters")["ignored parameters"] 

此外,如果隨後致電whererelation,你會返回一個斯塔Relation這將不再被扼殺。

+0

感謝您的迴應,但這只是返回最初的'MyClass.all'關係而不是我的存根響應。我應該琢磨一種不同的方法嗎? –

+0

當你說「this」只是返回最初的'MyClass.all'時,你指的是什麼? –

+0

對不起,當我的測試運行時,調用'MyClass.where(args args args)'它返回最初從'MyClass.all'返回的集合,而不是你在第2行寫的殘留集合。是:':[]'右邊方法? –