2014-01-25 3 views
5

레일즈 애플리케이션을 테스트하지 않습니다. 그냥 방해하지 마세요.스텁 ActiveRecord :: ActiveRecord 객체와의 관계

타임 스탬프별로 레코드를 제한하는 비교적 활동적인 서버에 연결하는 라이브러리를 테스트하고 있습니다. 이러한 반환 된 레코드는 시간이 지남에 따라 변경되므로 다른 제한 사항을 더 복잡하게 테스트 할 수 있습니다. ActiveRecord::where 메서드를 작성하여 필요한 기준을 충족시키기 위해 만든 개체와 내 사용자 지정 관계를 반환해야합니다.

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

같은

뭔가 내가 원하는 것입니다,하지만 작동하지 않습니다. 코드의 개체에 ActiveRecord::whereActiveRecord::select을 호출 할 수 있어야하므로 ActiveRecord::Relation이 필요합니다.


편집 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은 클래스이고 :[]은 그 클래스의 인스턴스 메소드입니다. 클래스 자체의 메소드를 스터 빙하고 있으므로 레일즈 코드에 의해 호출되지는 않습니다. 그러나

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

당신의 반환에 도착하기 위해 그주의 : 당신은 단지 :[] 스텁과의 관계를 돌아 MyClass.where을 원하는 경우에

, 당신은 같이 먼저 관계 인스턴스를 만들어야합니다 이후에 relationwhere를 호출하는 경우 당신이 새로운 채소를 돌아갑니다,

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

을 추가 :이 상황에서 배열, 당신은 수행해야합니다 nce는 Relation이며 더 이상 스터브되지 않습니다.

+0

응답 주셔서 감사합니다,하지만이 내 스텁 된 응답 대신 초기 'MyClass.all' 관계를 반환합니다. 다른 방법으로 스터 빙해야합니까? –

+0

"this"가 단지 초기 'MyClass.all'을 반환 할 때, 정확히 당신이 말하는 것은 무엇입니까? –

+0

미안, 내 테스트가 실행될 때,'MyClass.where (args args args) '를 호출하면 라인 2에서 작성한 스텁 된 콜렉션이 아니라'MyClass.all'에서 처음 리턴 된 콜렉션을 리턴합니다.': [] 방법? –

관련 문제