2013-04-29 6 views
0

나는 모델의 RSpec에 모의를 사용하여 컨트롤러에서 테스트를 만들려고 해요라고, 단지 내가RSpec에이

Type.any_instance.should_recieve(...) 

대신

instancename.should_receive(...) 
말할 때 작동하는 것 같다되지 조롱

내 코드는 다음과 같습니다. (일반적으로 내가 FactoryGirl를 사용하지만, 내가하지 오전이 예에서이 문제가 아니다 있는지 확인)

it "calls blah on foo" do 
    foo = Foo.new 
    foo.save 
    foo.should_receive(:blah) #this fails because it's called 0 times 
    #Foo.any_instance.should_receive(:blah) #this would succeed 
    post :create, {:foo => foo} 
end 

을 내 컨트롤러에

def create 
    foo = Foo.find_by_id(params[:foo]) 
    foo.blah 
    #other stuff thats not related 
end 

은 내가 Foo.find_by_id을 조롱 할 수 알고있다 그것은 foo를 리턴하지만, 어쨌든 리턴되어야하기 때문에 그렇게 할 필요가 없다고 생각합니다. find_by_id를 사용하지 않으면 테스트가 중단된다는 의미입니다. 이것은 중요한 세부 사항은 아닙니다.

내가 뭘 잘못하고 있는지 아는 사람이 있습니까? 나는 어디에서나 any_instance를 말할 필요가 없으며 find_by_id를 조롱 할 필요가 없다면 내 테스트가 나아질 것이라고 생각합니다. 그것은 당신의 실제 코드에 blah로 호출되고 같은 foo객체하지 않기 때문에

답변

2

코드는 작동하지 않습니다. 귀하의 사양 코드에서

, 당신은 인스턴스를 생성하고 저장 :

foo = Foo.new 
foo.save 

이는 DB에 foo 포인트 기록을 저장합니다. 이 기대에만 작동합니다

foo.should_receive(:blah) 

경우 같은 객체에 대한 사양 및 응용 프로그램 코드 포인트 : 당신은 다음 개체에 기대를했습니다. 예를 들어 find_by_id을 스터 빙하여 반환 할 수 있습니다. 또는 인스턴스에 대해 기대치를 설정할 수도 있습니다.

그러나 기대는 그대로 작동하지 않습니다. params[:foo]가 다음 레코드의 ID, 동일한 레코드에 앱 코드 포인트 모두 당신의 사양 코드 foofoo 경우

foo = Foo.find_by_id(params[:foo]) 
foo.blah 

:하지만, 실제 코드에서, 당신은 다른 객체 foo를 만들 그것이 그들이 같은 대상이라는 것을 의미하지는 않습니다 (그렇지 않습니다).

post :create, {:foo => foo} 

가 있어야한다 : 만약 내가 제대로 이해하고

또한, 나는이 있다고 생각

post :create, {:foo => foo.id} 

그래서, 간단히 말해서, 당신이 원하는 것은 메시지 기대하는 경우, 당신이 ' find을 스터핑하거나 모든 인스턴스에 기대치를 적용해야합니다. 동적 찾기가 find으로 전화를 걸기 때문에 find_by_id이 아닌 스텁 수는 find이어야하며 이는 테스트의 안정성을 높여줍니다.)

도움이 되길 바랍니다.

+0

감사합니다. 그것은 내가 생각한 것입니다. find_by_id를 호출하지 않고 방법이 있기를 바랬습니다. 찾기를 호출하면 더 나은 솔루션 인 것 같아서 그렇게 할 것입니다. – bdwain

+0

그냥 머리를 위로. find_by_id 호출 부분에 대한 부분이 작동한다고 생각하지 않습니다. 나는 그것을 시도하고 find_by_id로 전환 할 때까지 실패했다. – bdwain

+0

죄송합니다. 검토해 봐야겠다고 생각했는데, 어딘가에 있다고 생각했지만 잘못된 것일 수 있습니다. 너에게 다시 돌아갈 게. –