2009-11-08 4 views
4

특정 버전의 ActiveRecord에서만 실행해야하는 코드가 있습니다 (예전 AR 라이브러리의 버그에 대한 해결 방법). 이 코드는 ActiveRecord :: VERSION 상수의 값을 테스트하여 실행해야하는지 확인합니다.rspec mock을 사용하여 버전 상수를 스텁링 할 수 있습니까?

rspec에서 이러한 상수를 조롱하는 방법이 있습니까? 그렇다면 올바른 ActiveRecord 보석을 테스트 컴퓨터에 설치하지 않고 코드 경로를 테스트 할 수 있습니까?

답변

10

내가 코드 블록을 실행하는 동안 나 상수를 오버라이드 (override) 할 수있는 도우미 메서드 작성 결국 : 다음과 같이 spec_helper.rb 파일에이 코드를 넣어 후

def with_constants(constants, &block) 
    constants.each do |constant, val| 
    Object.const_set(constant, val) 
    end 

    block.call 

    constants.each do |constant, val| 
    Object.send(:remove_const, constant) 
    end 
end 

을, 그것은 사용할 수 있습니다

with_constants :RAILS_ROOT => "bar", :RAILS_ENV => "test" do 
    code goes here ... 
end 

희망이 당신을 위해 작동합니다.

+0

감사합니다. –

2

드류 올슨, 나는 범위 지정 추가 할 몇 가지 수정을 당신의 아이디어를 가져다가 만들어 다음과 같이 사양/지원/with_constants.rb 파일에서이 코드를 넣어 후

class Object 
    def self.with_constants(constants, &block) 
    old_constants = Hash.new 
    constants.each do |constant, val| 
     old_constants[constant] = const_get(constant) 
     silence_stderr{ const_set(constant, val) } 
    end 

    block.call 

    old_constants.each do |constant, val| 
     silence_stderr{ const_set(constant, val) } 
    end 
    end 
end 

을, 그것은 사용할 수 있습니다

MyModel.with_constants :MAX_RESULT => 2, :MIN_RESULT => 1 do 
    code goes here ... 
end 
+0

코드를 호출하기 전에 메소드를 스텁 처리 할 때'''Kernel :: silence_warnings {const_set (constant, val)}'''대신'''silence_stderr {const_set (constant, val)}'''을 사용하십시오. –

1

테스트 블록에서 다른 테스트의 복원 상수를 확인하려면 복구 블록을 추가하는 것이 중요합니다!

class Object 
    class << self 
    def with_constants(constants, &block) 
     old_constants = Hash.new 
     constants.each do |constant, val| 
     old_constants[constant] = const_get(constant) 
     Kernel::silence_warnings { const_set(constant, val) } 
     end 

     error = nil 
     begin 
     block.call 
     rescue Exception => e 
     error = e 
     end 

     old_constants.each do |constant, val| 
     Kernel::silence_warnings { const_set(constant, val) } 
     end 

     raise error unless error.nil? 
    end 
    end 
end 

일반적으로

RSpec에 2.11로
describe "#fail" do 

    it "should throw error" do 
    expect { 
     MyModel.with_constants(:MAX_RESULT => 1) do 
     # code with throw error 
     end 
    }.to raise_error 
    end 

end