2011-12-04 5 views
2

RSpec에 컨트롤러의 사양에 조롱이 간단한 동작을 테스트하는 중에, 나는 아주 추악하고 강력한 모의 구조로 결국 리팩토링은 내가 <code>new</code> 활동과 더불어, <code>TopicsController</code>이

def new 
    @section = Section.find(params[:section_id]) 
    @topic = @section.topics.build 
end 

describe "#new" do 
    it "builds a topic with a given section" do 
    new_topic = mock_model(Topic) 
    topics = mock('topics') 
    topics.should_receive(:build).and_return(new_topic) 

    section = mock_model(Section) 
    section.should_receive(:topics).and_return(topics) 

    Section.should_receive(:find).with("1").and_return(section) 
    get :new, :section_id => 1 

    assigns[:topic].should == new_topic 
    end 
end 

이 코드를 더 간단하게 만들고 싶지만 어떻게 보이지 않습니다. 나는 @section mock을 제거 할 수 없으며, 연결 설정 .topics.build 호출에 대한 특정 값을 반환해야만 기대를 설정할 수 있습니다.

더 간단한 방법이 있나요? RSpec 2.7을 사용하고 있습니다.

답변

4
describe TopicsController do 
    specify :new do 
    section = stub_chain(:topics, :build).and_return(:new_topic) 
    Section.should_receive(:find).with(1).and_return(section) 

    get :new, section_id: 1 

    assigns_should_match section: section, topic: :new_topic 
    end 
end 

def assigns_should_match(h) 
    h.each { |k,v| assigns[k].should == v } 
end 
-4

컨트롤러 사양은 불필요하게 고통 스럽습니다. 대신에 오이 시나리오 (모의가 아닌 실제 개체 포함)를 작성하십시오.

+1

오이는이 질문에 대한 해결책이 아닙니다. 오이는 수용 테스트 (또는 통합 테스트를 위해 실제로 사용하기를 원하는 경우 통합 테스트 용)이므로 컨트롤러를 테스트하는 데 익숙하지 않아야합니다. 잘못된 것의 경우 오이를 사용하여 느리고 관리하기 어려운 검사로 끝날 것입니다. – twe4ked

+0

@odin 통합 테스트 (예 : 오이 스토리)는 실제로 대부분의 경우 컨트롤러를 테스트 할 수있는 유일한 방법입니다 (예외는 API 끝점 인 컨트롤러의 경우 일 수 있음). 일반적으로 Rails 컨트롤러는 단위 테스트가 필요하지 않습니다 (모델 및 유사한 객체 만 해당). 실제로 컨트롤러 유닛 테스트는 잘못된 것을 테스트하는 경향이 있으므로 그렇지 않은 경우 컨트롤러가 제대로 테스트되지 않았다고 생각하게 만듭니다. 그래서 예 ... 오이 *는 여기에 적절한 해결책입니다. –

관련 문제