2012-12-15 6 views
14

어떤 클래스의 인스턴스를 스텁하려고합니다. fetch 메서드를 스텁 (stub)해야합니다.이 메서드는 자체 데이터를 일부 데이터로 채 웁니다.RSpec any_instance return self

self 변수에 액세스하여 수정하고 fetch 방법으로 돌아갈 수있는 방법은 무엇입니까?

MyObject.any_instance.stub(:fetch) { self } 

MyObject 인스턴스를 반환하지 않습니다.

아마도 이러한 상황에서는 mocks가 더 유용합니다. 불행히도, 나는 아직 그들을 이해하지 못했다.

답변

1

필자가 볼 수있는 한, 이는 어떤 이유로 든 가능하지 않습니다. 나는 현재 rspec-mocks 구현을 확인하고, 실제로 스텁 구현을 호출하는 방법은 다음과 같은 것으로 보인다 보인다으로

# lib/rspec/mocks/message_expectation.rb:450 
def call_implementation(*args, &block) 
    @implementation.arity == 0 ? @implementation.call(&block) : @implementation.call(*args, &block) 
end 

, 블록은 단순히 instance_eval을 통해 자체에 의해 호출되고 있지 않습니다. 아마 당신이 원하는 것을 얻기위한 또 다른 기술이 있습니다. 어쨌든 나는 RSpec 전문가가 아닙니다.

12

이 문제를 해결하려면 open rspec-mocks issue이 있습니다. 어떤 점에서이 문제를 해결하기 위해 노력하고 싶지만, 블록 구현시 any_instance을 사용하는 기존 사양 스위트를 손상시키지 않는 방식으로이를 추가하는 것은 간단하지 않습니다. 추가 인수 (예 : 객체 예).

전반적으로 어떤 상황에서는 any_instance이 유용 할 수 있지만 약간의 냄새가납니다. 개별 인스턴스를 조롱하거나 스텁하는 방법을 찾으면 일반적으로 문제가 줄어 듭니다.

는 여기가 테스트하지 않았습니다 만 작동해야하는 일을 주위의 :

orig_new = MyObject.method(:new) 
MyObject.stub(:new) do |*args, &block| 
    orig_new.call(*args, &block).tap do |instance| 
    instance.stub(:fetch) { instance } 
    end 
end 

을 기본적으로, 우리는 우리가 인스턴스화 될 때마다 새로운 인스턴스에 fetch 스텁 수 있도록하는 MyObject.new에 접선에 의해 여기 any_instance을 시뮬레이션하고 있습니다.

"테스트를 듣는 것이 중요합니다"라고 말하면서, 테스트하기 어려운 것이있을 때 any_instance과 같은 전동 공구를 사용하기보다는 디자인에 대해 무엇을 말하고 있는지를 모두 고려해야합니다. 원래의 질문은 내가 디자인에 대해 추측 할 수있는 충분한 컨텍스트를 제공하지 않지만이 작업을 수행해야 할 때 분명히 시작할 것입니다.

+0

나는 좋은 일을했습니다! 많은 감사합니다! – jethroo