Rspec with inherited_resources перенаправляет вместо рендеринга при неудачном обновлении - PullRequest
1 голос
/ 10 мая 2011

Я новичок как в rspec, так и в унаследованных ресурсах. У меня есть простой ресурс, Контакт, который имеет поле имени. Контроллер не имеет специальных функций.

class ContactsController <  InheritedResources::Base 
  actions :all, :except => [:show]
end

Я написал спецификации для создания и индексации просто отлично, используя mock_model. Однако при использовании mock_model при обновлении он не мог найти контакт при установке. Итак, я перешел на использование реальных моделей:

describe "PUT update" do
let(:contact) { Contact.create(:name => "test 1") }

it "edits the contact" do
  contact.name = "#{contact.name}-edited"
end
context "when the contact updates successfully" do
  before do
    contact.stub(:save).and_return(true)
  end
  it "redirects to the Contacts index" do
    put :update, :id => contact.id, :contact => contact
    #assigns[:contact].name = "test 1 - edited"
    response.should redirect_to(:action => "index")
  end
end

context "when the contact fails to save" do
  before do
    contact.stub(:save).and_return(false)
    contact.stub(:update_attributes).and_return(false)
    contact.stub(:errors).and_return(:errors => { :anything => "anything" })
  end
  it "renders the edit template" do
    put :update, :id => contact.id, :contact => contact
    response.should render_template :edit
  end
end
end

Я получаю следующую ошибку:

Failures:

  1) ContactsController PUT update when the contact fails to save renders the edit template
   Failure/Error: response.should render_template :edit
   Expected block to return true value.
   # ./spec/controllers/contacts_controller_spec.rb:82:in `block (4 levels) in <top (required)>'

Когда я проверяю код_состояния, это редирект 302 в /contacts/:id.

Что я делаю не так?

1 Ответ

3 голосов
/ 10 мая 2011

Это действительно распространенная проблема, когда люди начинают использовать макеты в тестах контроллера.Вы заглушаете методы для объекта, который является локальным для спецификации.Когда вы получаете доступ к вашему контроллеру с помощью put, InheritedResources вызывает Contact.find(params[:id]) и возвращает свой собственный объект, не объект, к которому вы хотите.выполняется без проблем и перенаправляет обратно на страницу show объекта.

Общее исправление для этого состоит в том, чтобы также смоделировать метод find в вашей модели, чтобы он вместо этого возвращал ваш заглушенный объект вместодругой.

Contact.should_receive(:find).and_return(contact)
contact.should_receive(:update_attributes).and_return(false)
put :update, :id => contact.id, # etc.
...