LoginSignup
3
3

More than 5 years have passed since last update.

respond_with について調べてみた

Last updated at Posted at 2014-07-21

きっかけ

inherited_resourcesを導入して、scaffoldで生成したspecの中、POST create invalidPUT update invalidupdateのケースがエラーになったので、調べてみました

環境

  • Rails 4.1.4
  • Ruby 2.1.2

エラーのケース

it "re-renders the 'new' template" do
  # Trigger the behavior that occurs when invalid params are submitted
  Journal.any_instance.stub(:save).and_return(false)
  post :create, {:journal => { "title" => "invalid title" }}, valid_session
  response.should render_template(:new)
end

it "re-renders the 'edit' template" do
  journal = Journal.create! valid_attributes
  # Trigger the behavior that occurs when invalid params are submitted
  Journal.any_instance.stub(:save).and_return(false)
  put :update, {:id => journal.to_param, :journal => { "title" => "invalid title" }}, valid_session
  response.should render_template(:edit)
end

it "updates the requested journal" do
  journal = Journal.create! valid_attributes
  # Assuming there are no other journals in the database, this
  # specifies that the Journal created on the previous line
  # receives the :update_attributes message with whatever params are
  # submitted in the request.
  Journal.any_instance.should_receive(:update).with({ "title" => "MyString" })
  put :update, {:id => journal.to_param, :journal => { "title" => "MyString" }}, valid_session
end

内容

Failures:

  1) JournalsController PUT update with invalid params re-renders the 'edit' template
     Failure/Error: response.should render_template(:edit)
       expecting <"edit"> but rendering with <[]>
     # ./spec/controllers/journals_controller_spec.rb:122:in `block (4 levels) in <top (required)>'
     # -e:1:in `<main>'

  2) JournalsController POST create with invalid params re-renders the 'new' template
     Failure/Error: response.should render_template(:new)
       expecting <"new"> but rendering with <[]>
     # ./spec/controllers/journals_controller_spec.rb:78:in `block (4 levels) in <top (required)>'
     # -e:1:in `<main>'

  3) JournalsController PUT update with valid params updates the requested journal
     Failure/Error: Unable to find matching line from backtrace
       Exactly one instance should have received the following message(s) but didn't: update

エラーの原因

1,2 の原因

  • inherited_resourcesrespond_withメソッドを活用している
  • respond_withRespondercallto_htmlnavigation_behaviorの順んで呼び出される
https
def navigation_behavior(error)
  if get?
    raise error
  elsif has_errors? && default_action
    render :action => default_action
  else
    redirect_to navigation_location
  end
end
...
def has_errors?
  resource.respond_to?(:errors) && !resource.errors.empty?
end
  • エラーがあるかどうかの判定は、resource.errors.empty?で判定している
  • そして、specの中は、Journal.any_instance.stub(:save).and_return(false)のようにstubでエラーにさせようとしているが、上記の判定条件に引っかからない為、最後のredirect_to navigation_locationに至ってしまう流れです。

3の原因

  • inherited_resourcesはまだupdate_attributesを使っているので、それに合わせれば良い

対応方法

  • specstubをやめて、自分のプロジェクトのロジックをみてちゃんとinvalidのパラメータを渡せばよい
  • うちの場合、Journaltitleが必須入力なのんで、titlenilに渡すように修正すれば、全specパスできました。
it "re-renders the 'new' template" do
  # Trigger the behavior that occurs when invalid params are submitted
  # Journal.any_instance.stub(:save).and_return(false)
  post :create, {:journal => { "title" => nil }}, valid_session
  response.should render_template(:new)
end

it "re-renders the 'edit' template" do
  journal = Journal.create! valid_attributes
  # Trigger the behavior that occurs when invalid params are submitted
  # Journal.any_instance.stub(:save).and_return(false)
  put :update, {:id => journal.to_param, :journal => { "title" => nil }}, valid_session
  response.should render_template(:edit)
end

it "updates the requested journal" do
  journal = Journal.create! valid_attributes
  # Assuming there are no other journals in the database, this
  # specifies that the Journal created on the previous line
  # receives the :update_attributes message with whatever params are
  # submitted in the request.
  Journal.any_instance.should_receive(:update_attributes).with({ "title" => "MyString" })
  put :update, {:id => journal.to_param, :journal => { "title" => "MyString" }}, valid_session
end

参考リンク

respond_to について調べてみた

josevalim/inherited_resources

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3