我在學習Rails以及如何使用RSpec進行測試。我需要幫助完成PUT更新操作的RSpec控制器測試。控制器指導一個嵌套的資源。嵌套的路線和相關的程序代碼在Web瀏覽器中按預期工作。我只需要幫助編寫PUT更新操作的RSpec測試。我已經通過了控制器執行的其他操作的測試。RSpec控制器測試嵌套資源上的PUT更新操作
我知道父路徑和子路徑都必須傳遞給put方法,但我對以下內容感到困惑:(1)如何使用FactoryGirl對象正確設置PUT更新測試,以及2)正確的RSpec語法將路徑和ID傳遞給PUT方法。
從耙路線相關的路線:
PATCH /members/:member_id/cardio_exercises/:id(.:format) cardio_exercises#update
PUT /members/:member_id/cardio_exercises/:id(.:format) cardio_exercises#update
routes.rb中包含: 資源:會員做 資源:cardio_exercises 結束
members.rb包含: 的has_many:cardio_exercises,:依賴=>:破壞
cardio_exercises.rb包含: belongs_to:成員
個相關工廠:
FactoryGirl.define do
factory :cardio_exercise do
title "My cardio exercise"
duration 30
calories_burned 300
date "2014-11-15"
association :member
end
end
FactoryGirl.define do
factory :member do
first_name {Faker::Name.first_name}
last_name {Faker::Name.last_name}
age 21
height 75
weight 195
goal "fffff" * 5
start_date "2014-11-15"
end
end
的cardio_exercises_controller.rb
class CardioExercisesController < ApplicationController
# :get_member is defined in the private method at the bottom of this file,
# and takes the member_id provided by the routing and
#converts it to a @member object.
before_action :get_member
# GET member/1/cardio_exercises
# GET member/1/cardio_exercises.json
def index
@cardio_exercises = @member.cardio_exercises
end
# GET member/1/cardio_exercises/1
# GET member/1/cardio_exercises/1.json
def show
cardio_exercise = @member.cardio_exercises.find(params[:id])
end
# GET member/1/cardio_exercises/new
def new
@member = Member.find(params[:member_id])
@cardio_exercise = @member.cardio_exercises.build
end
# GET member/1/cardio_exercises/1/edit
def edit
@cardio_exercise = @member.cardio_exercises.find(params[:id])
end
# POST member/1/cardio_exercises
# POST member/1/cardio_exercises.json
def create
@cardio_exercise = @member.cardio_exercises.build(cardio_exercise_params)
if @cardio_exercise.save
flash[:success] = "Cardio exercise was successfully created."
redirect_to member_cardio_exercises_path(@member)
else
render 'new'
end
end
# PATCH/PUT member/1/cardio_exercises/1
# PATCH/PUT member/1/cardio_exercises/1.json
def update
@cardio_exercise = @member.cardio_exercises.find(params[:id])
if @cardio_exercise.update(cardio_exercise_params)
flash[:success] = "Cardio exercise was successfully updated."
redirect_to member_cardio_exercises_path(@member)
else
render 'edit'
end
end
# DELETE member/1/cardio_exercises/1
# DELETE member/1/cardio_exercises/1.json
def destroy
@cardio_exercise = @member.cardio_exercises.find(params[:id])
@cardio_exercise.destroy
respond_to do |format|
format.html { redirect_to (member_cardio_exercises_path(@member)), notice: 'Cardio exercise was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# The get_member action converts the member_id given by the routing
# into an @member object, for use here and in the view.
def get_member
@member = Member.find(params[:member_id])
end
def cardio_exercise_params
params.require(:cardio_exercise).permit(:title, :duration, :calories_burned, :date, :member_id)
end
end
的cardio_exercises_controller_spec.rb和我試圖建立PUT更新動作的幾個測試:
require 'rails_helper'
RSpec.describe CardioExercisesController, :type => :controller do
before :each do
@member = FactoryGirl.create(:member)
@cardio_exercise = FactoryGirl.create(:cardio_exercise, member: @member)
@cardio_exercise_attributes = FactoryGirl.attributes_for(:cardio_exercise, :member_id => @member)
@cardio_exercise_update_attributes = FactoryGirl.attributes_for(:cardio_exercise, :title => "Your Cardio Exercise", :member_id => @member)
end
describe "GET index" do
it "assigns all cardio_exercises as @member.cardio_exercises" do
get :index, { :member_id => @member }
expect(assigns(:cardio_exercises)).to eq(@member.reload.cardio_exercises)
end
end
describe "GET show" do
it "assigns the requested cardio_exercise as @cardio_exercise" do
get :show, { :member_id => @member, :id => @cardio_exercise }
expect(assigns(:cardio_exercise)).to eq(@cardio_exercise)
end
end
describe "GET new" do
it "assigns a new cardio_exercise as @member.cardio_exercise" do
get :new, { :member_id => @member }
expect(assigns(:cardio_exercise)).to be_a_new(CardioExercise)
end
end
describe "GET edit" do
it "assigns the requested cardio_exercise as @member.cardio_exercise" do
get :edit, { :member_id => @member, :id => @cardio_exercise }
expect(assigns(:cardio_exercise)).to eq(@cardio_exercise)
end
end
describe "POST create" do
describe "with valid params" do
it "creates a new CardioExercise" do
expect {
post :create, { :member_id => @member, :cardio_exercise => @cardio_exercise_attributes }
}.to change(CardioExercise, :count).by(1)
end
it "assigns a newly created cardio_exercise as @cardio_exercise" do
post :create, { :member_id => @member, :cardio_exercise => @cardio_exercise_attributes }
expect(assigns(:cardio_exercise)).to be_a(CardioExercise)
expect(assigns(:cardio_exercise)).to be_persisted
end
it "redirects to the created cardio_exercise" do
post :create, { :member_id => @member, :cardio_exercise => @cardio_exercise_attributes }
expect(response).to redirect_to(member_cardio_exercises_path(@member))
end
end
end
describe "PUT update" do
describe "with valid params" do
it "updates the requested cardio_exercise" do
put :update, { :member_id => @member, :id => @cardio_exercise_update_attributes }
@member.cardio_exercise.reload
put :update, { :member_id => @member, :id => @cardio_exercise_update_attributes}
end
it "assigns the requested cardio_exercise as @member.cardio_exercise" do
put :update, { :member_id => @member, :cardio_exercise => @cardio_exercise_update_attributes = FactoryGirl.attributes_for(:cardio_exercise, :title => "Your Cardio Exercise", :member_id => @member)}
expect(assigns(:cardio_exercises)).to eq(@member.cardio_exercises)
end
it "redirects to the cardio_exercise" do
put :update, { :member_id => @member, :id => @cardio_exercise }
expect(response).to redirect_to(@member.cardio_exercise)
end
end
describe "with invalid params" do
xit "assigns the cardio_exercise as @member.cardio_exercise" do
end
xit "re-renders the 'edit' template" do
expect(response).to render_template("edit")
end
end
end
describe "DELETE destroy" do
it "destroys the requested cardio_exercise" do
expect {
delete :destroy, { :member_id => @member, :id => @cardio_exercise }
}.to change(CardioExercise, :count).by(-1)
end
it "redirects to the cardio_exercises list" do
delete :destroy, { :member_id => @member, :id => @cardio_exercise }
expect(response).to redirect_to(member_cardio_exercises_url)
end
end
end
請檢查我的測試設置和PUT更新測試。具體來說,我設置了測試PUT更新操作的正確方法嗎?
如何更改控制器的更新動作的設置和/或測試,因此:
(1)我的測試符合我的更新動作路線?
(2)我在正確的RSpec語法中傳遞必要的父級和子級ID以便可以找到記錄?
我感謝任何幫助!
你有沒有試圖改變'''通過在測試中'patch'' put''?請記住,Rails 4使用PATCH進行更新調用。 – dgilperez 2015-02-11 23:11:57
嘗試過修補程序,但生成的相同記錄未找到/路由不匹配錯誤。這個問題似乎與我如何設置更新操作的測試有關。 – codeinspired 2015-02-11 23:20:23