Рефакторинг макетов в спецификациях контроллера RSpec - PullRequest
2 голосов
/ 04 декабря 2011

У меня есть TopicsController с действием new:

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, и он должен возвращать что-то конкретное в цепочечном вызове .topics.build, чтобы позволить мне установить ожидание.

Есть ли более простой способсделать это? Я использую RSpec 2.7.

Ответы [ 2 ]

4 голосов
/ 04 декабря 2011
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
0 голосов
/ 05 декабря 2011

Спецификации контроллера, как вы выяснили, безнадежно болезненны.Вместо этого напишите сценарий Cucumber (с реальными объектами, а не с имитаторами).

...