2013-06-07 5 views
3

레일즈 애플리케이션에서 하나의 클래스를 a gem으로 추출했습니다. 그것은 매우 간단하지만 물론 완전히 테스트하고 싶습니다 (저는 rspec을 사용하고 있습니다).ActiveSupport가 필요하거나없는 유닛 테스트

클래스는 간단한 날짜 계산을 수행합니다. Rails에 의존하지 않지만 Rails 앱에서 시작하여 아직 사용 중이기 때문에 가능하면 ActiveSupport의 시간대 인식 메소드를 사용합니다. 그러나 ActiveSupport를 사용할 수없는 경우 std-lib Date 메서드를 사용해야합니다.

특히, 그것은 단지이 하나 개의 장소에서 수행합니다

arg ||= if Date.respond_to?(:current) 
    Date.current # use ActiveSupport's time zone-aware mixin if possible 
else 
    Date.today # stdlib fallback 
end 

질문은 다음과 같습니다 : 어떻게 제대로이 테스트합니까 "오늘 날짜가"할 수있는 선택적 인수를 디폴트? 내 spec_helper.rb에 ActiveSupport가 필요하면 분명히 을 사용하십시오. 아무데도 필요하지 않으면 절대 사용하지 않을 것입니다. 그리고 하나의 예제 그룹에서 필요로하는 경우 rspec의 임의의 실행 순서는 AS가 필요할시기를 알지 못하기 때문에 테스트를 예측할 수 없게 만듭니다.

중첩 된 그룹이 내 생각에 최상위에서 최하위로 처리되기 때문에 중첩 된 그룹의 before(:all)에서 필요로 할 수 있습니다. 그러나 그것은 대단히 부끄럽다.

스펙을 두 개의 파일로 분리하여 별도로 실행할 수도 있지만 다시는 불필요한 것으로 보입니다.

또한 rspec의 임의 순서를 사용하지 못하게 할 수도 있지만 그게 곡식과 일종의 관계입니다. 나는 그것을 가능한 한 무작위로 얻고 싶습니다.

아이디어가 있으십니까?

답변

2

또 다른 해결책은 currenttoday 방법을 조롱하고 테스트를 위해 사용하는 것입니다. 예를 들면 :

# you won't need these two lines, just there to make script work standalone 
require 'rspec' 
require 'rspec/mocks/standalone' 

def test_method(arg = nil) 
    arg ||= if Date.respond_to?(:current) 
     Date.current # use ActiveSupport's time zone-aware mixin if possible 
    else 
     Date.today # stdlib fallback 
    end 
    arg 
end 

describe "test_method" do 
    let(:test_date) { Date.new(2001, 2, 3) } 
    it "returns arg unchanged if not nil" do 
     test_method(34).should == 34 
    end 

    context "without Date.current available" do 
     before(:all) do 
      Date.stub(:today) { test_date } 
     end 
     it "returns Date.today when arg isn't present" do 
      test_method.should == test_date 
     end 
    end 

    context "with Date.current available" do 
     before(:all) do 
      Date.stub(:current) { test_date } 
     end 
     it "returns Date.current when arg isn't present" do 
      test_method.should == test_date 
     end 
    end 
end 

이 통과하는 테스트에서 rspec test.rb 결과를 실행합니다.

또한, 스텁은 각 컨텍스트에 존재하는, 그래서 사양이 실행됩니다 주문할 중요하지 않습니다

+0

물론! 스펙에있는 다른 모든 것이 매우 간단하기 때문에 스텁을 고려하지 않았습니다. 왜 내가 질문을 할 때마다 대답을 얻을 때 나는 완전한 dunce처럼 느껴지나요? :)하지만 상관없이 감사합니다! :) – Flambino

0

이것은 약간 이상한 것이지만 이어야합니다. 다음 ActiveSupport 등을 포함합니다 :

context "without ActiveSupport's Date.current" do 
    before(:each) do 
    class Date 
     class << self 
     alias_method :current_backup, :current 
     undef_method :current 
     end 
    end 
    end 

    # your test 

    after(:each) do 
    class Date 
     class << self 
     alias_method :current, :current_backup 
     end 
    end 
    end 
end 

정말 이것을 권장하지 않습니다; 나는 당신이 제안한 것처럼이 하나의 스펙을 분리하여 따로 실행하는 것을 선호한다.

+0

훗, 나는 나 자신을 고려,하지만 당신이 말한대로 :. 그것은 좀 비뚤어진입니다 :) 그 말했다, 아마 그것은 단지 잘게 될 것이다. .. 그러나 조용한 다음과 같은 총체 :) – Flambino