2015-02-11 95 views
3

我在學習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以便可以找到記錄?

我感謝任何幫助!

+0

你有沒有試圖改變'''通過在測試中'patch'' put''?請記住,Rails 4使用PATCH進行更新調用。 – dgilperez 2015-02-11 23:11:57

+0

嘗試過修補程序,但生成的相同記錄未找到/路由不匹配錯誤。這個問題似乎與我如何設置更新操作的測試有關。 – codeinspired 2015-02-11 23:20:23

回答

4

您必須通過member_id,該cardio_exercise的id,和cardio_exercise參數更新:

put :update, { 
    :member_id => @member, 
    :id => @cardio_exercise.id, 
    :cardio_exercise => @cardio_exercise_update_attributes 
} 
+0

Thanks @infused,添加cardio_exercise參數會導致第一個PUT測試通過。不幸的是,第二次和第三次測試失敗,未定義的方法錯誤'cardio_exercise'for#不明白爲什麼我在這些測試中沒有方法錯誤。 – codeinspired 2015-02-12 01:07:14

+0

該錯誤發生在哪行代碼上? – infused 2015-02-12 01:09:40

+0

rspec ./spec/controllers/cardio_exercises_controller_spec。rb:79#CardioExercisesController PATCH更新與有效的參數分配請求cardio_exercise作爲@ member.cardio_exercise – codeinspired 2015-02-12 01:11:03

相關問題