はじめに
Rails Tips の 28 回目です。今日も update の request_spec を説明します。テストの雛形は以下のようになります。
# describe "PATCH #update" do # subject { -> { patch <%= singular_table_name %>_path(one), params: {<%= singular_table_name %>: attrs} } } # context "owned object" do # let(:one) { object } # context "正しいパラメータに対して" do # before { attrs["sort_order"] = 1 } # it_behaves_like "レスポンスコード確認", 302 # it_behaves_like "オブジェクト属性が変化した?", <%= class_name %>, :sort_order, 1 # it_behaves_like "リダイレクト確認" # it_behaves_like "Notice メッセージ確認", "XXXを更新しました。" # end # context "不正なパラメータに対して" do # before { attrs["name"] = "" } # it_behaves_like "レスポンスコード確認", 422 # it_behaves_like "オブジェクト属性が変化しない?", <%= class_name %>, :name # it_behaves_like "Alert メッセージ確認", "XXXの更新に失敗しました。" # end # end # context "not owned object" do # let(:one) { not_mine } # it_behaves_like "レスポンスコード確認", 302 # it_behaves_like "rootリダイレクト確認" # end # end
オブジェクト属性が変化しない?
以下は昨日の緊急連絡先 (EmergencyCall) を作成する update の異常系の spec になります。before で属性の tel を変更した上で patch が呼ばれます。レスポンスコード確認、Alert メッセージ確認は create と同様です。今回新規で登場するのは「オブジェクト属性が変化しない?」になります。属性名を渡すことでその属性値が変更されなかったことを確認します。
context "不正なパラメータに対して" do before { attrs["tel"] = "" } it_behaves_like "レスポンスコード確認", 422 it_behaves_like "オブジェクト属性が変化しない?", EmergencyCall, :name it_behaves_like "Alert メッセージ確認", "緊急連絡先の更新に失敗しました。" end
この shared_example は以下のようになります。属性が変わらないことを確認します。
shared_examples_for "オブジェクト属性が変化しない?" do |klass, key| it "#{klass} の #{key} が変化しないこと" do expect { subject.call }.not_to change(klass.find(object.id), key) end end
正しく動作させるための実装
update に失敗した場合、まず flash を設定し、edit action を描画します。この時、status は unprocessable_entity
にしておきます。update に失敗しているので、属性が変わらないのでテストは成功するはずです。
if @emergency_call.update emergency_call_params redirect_to gakusei_path(@gakusei), notice: notice_message(EmergencyCall) else flash.now[:alert] = alert_message EmergencyCall render action: :edit, status: :unprocessable_entity end
おわりに
update が完了したので、明日は最後の destroy になります。