2013-09-03 3 views
0

나는 상관하지 않는 많은 수의 메시지를받을 수있는 객체를 조롱하고 싶다. 나는이 객체가 'true'와 같은 기본 응답을 가지기를 원한다. 특정 메소드와 응답을 추가 할 수있는 기능이 중요하다. RSpec에서이 작업을 수행 할 수 있습니까? 내가 원하는 것은이 같은 것입니다 :기본 응답으로 rspec 이중을 사용할 수 있습니까?

obj = default_double(default: true, widget_count: 5) 
obj.foobar.should == true 
obj.widget_count.should == 5 

나는 반환 값으로 람다 또는 PROC에 전달하고 default_double 반환에게 그 람다의 평가를 할 수 있다면 좋을 것입니다. proc 또는 lambda가 예제에서 사용 가능한 변수에 대한 액세스와 함께 테스트 컨텍스트에서 평가 된 경우에는 매우 유용 할 것입니다. 특징은 위의 추가 된 경우

그래서, 우리는 같은 것을있을 수 있습니다 :이 기능에 대한 동기 부여가 독자에게 흥미있는 경우

@widgets = WidgetContainer.new 
@widgets.widget_count = 5 
obj = default_double(default: true, widget_count: lambda { @widgets.widget_count }) 
obj.foobar.should == true 
obj.widget_count.should == 5 

을의 내가 파고 찾으려하지 않는 하나 있다고 가정하자 수신 할 수있는 모든 가능한 메시지를 제거하거나 가능한 메시지 집합이 매우 크거나 알 수없는 경우.

이와 비슷한 것이 RSpec에 내장되어 있습니까?

+0

을이 기능을 원하는 이유는 무엇입니까 : 그것은 몇 가지 리팩토링 혜택을 누릴 수 있지만

다음은 위의 예를 전달 그것에서 잘라입니까? 나는 그것을위한 유스 케이스를 전혀 보지 못했다. –

+0

필자는 존재해야하고 다양한 메시지에 응답해야하는 복잡한 개체 계층 구조의 개체를 가지고 있지만 실제로 그것에 대해서는 아무 상관이 없습니다. 이것은 일종의 로거 객체입니다. 반환 값은 대단히 중요하지 않지만 호출 된 메소드에 응답하는 것은 중요합니다. 내 선택은 전체 거대한 애플 리케이션을 통해 grovel이며,이 개체에 무엇을 호출하고 그들을 스텁, 내 테스트를 위해 아마도 불필요하게 많은, 또는 그냥 기본 응답을 가지고 그 방법에 대한 구체적인 반환 값이 필요합니다. –

+0

그런 말을하고 싶습니다. 사실에 초점을 맞춘 의견/답변을 계속하고 싶습니다. RSpec은 가짜에 대한 기본값을 제공 할 수도 있고 제공 할 수도 없습니다. 그럴 수 없다는 것을 알게되면, "아니오, 할 수 없다"는 훌륭한 대답입니다. –

답변

0

좋아, 내가 질문에 대답에서 촬영 할게요 :

내가 가진 RSpec에이 하지 않는다는 것을 생각 내장 된 임의의 메시지를 수신하고 기본 값을 반환 모의 기능을 제공합니다. 그러나 Ruby의 method_missing 기능과 함께 반환 값을 블록으로 지정하면 위에서 설명한 default_double 메서드를 쉽게 만들 수 있습니다.

require 'spec_helper' 

def default_double(args) 
    object = Object.new 
    args.each do |key, value| 
    if key == :default 
     object.define_singleton_method(:method_missing) { |method, *args, &block| value } 
    elsif Proc === value 
     expect(object).to receive(key) do value.call end 
    else expect(object).to receive(key).and_return(value) 
    end 
    end 
    object 
end 

class WidgetContainer 
    attr_accessor :widget_count 
end 

describe "default_double test" do 
    it "should pass" do 
    @widgets = WidgetContainer.new 
    @widgets.widget_count = 5 
    obj = default_double(default: true, widget_count: lambda { @widgets.widget_count }) 
    obj.foobar.should == true 
    obj.widget_count.should == 5 
    end 
end 
+0

맞아. 그건 내가해야 할 일이라고 생각했지만, 우아하고 멋지다. 나는 당신의 구현을 좋아한다. 나는 수동으로 method_missing으로 클래스를 생성하고 디폴트 값을 리턴하고 있었다. 이것은 훨씬 낫다. 감사! –

관련 문제