RSpec 嵌套资源上 PUT 更新操作的控制器测试
RSpec controller tests of PUT update action on nested resource
我正在学习 Rails 以及如何使用 RSpec 进行测试。我需要帮助完成 PUT 更新操作的 RSpec 控制器测试。控制器控制嵌套资源。嵌套路由和相关程序代码在 Web 浏览器中按预期工作。我只需要帮助为 PUT 更新操作编写 RSpec 测试。我已经通过了控制器执行的其他操作的测试。
我知道必须将路径以及父子 ID 传递给 put 方法,但我对以下内容感到困惑:(1) 如何使用 FactoryGirl 对象正确设置 PUT 更新测试,以及(2) 将路径和 ID 传递到 PUT 方法的正确 RSpec 语法。
来自rake路线的相关路线:
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, :dependent => :destroy
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 更新操作的正确方法?
如何更改控制器更新操作的设置 and/or 测试,以便:
(1) 我的测试与更新操作的路由匹配?
(2) 我以正确的 RSpec 语法传递必要的父 ID 和子 ID,以便可以找到记录?
感谢任何帮助!
您必须传递 member_id
、cardio_exercise 的 id
和 cardio_exercise
参数才能更新:
put :update, {
:member_id => @member,
:id => @cardio_exercise.id,
:cardio_exercise => @cardio_exercise_update_attributes
}
我正在学习 Rails 以及如何使用 RSpec 进行测试。我需要帮助完成 PUT 更新操作的 RSpec 控制器测试。控制器控制嵌套资源。嵌套路由和相关程序代码在 Web 浏览器中按预期工作。我只需要帮助为 PUT 更新操作编写 RSpec 测试。我已经通过了控制器执行的其他操作的测试。
我知道必须将路径以及父子 ID 传递给 put 方法,但我对以下内容感到困惑:(1) 如何使用 FactoryGirl 对象正确设置 PUT 更新测试,以及(2) 将路径和 ID 传递到 PUT 方法的正确 RSpec 语法。
来自rake路线的相关路线:
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, :dependent => :destroy
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 更新操作的正确方法?
如何更改控制器更新操作的设置 and/or 测试,以便:
(1) 我的测试与更新操作的路由匹配?
(2) 我以正确的 RSpec 语法传递必要的父 ID 和子 ID,以便可以找到记录?
感谢任何帮助!
您必须传递 member_id
、cardio_exercise 的 id
和 cardio_exercise
参数才能更新:
put :update, {
:member_id => @member,
:id => @cardio_exercise.id,
:cardio_exercise => @cardio_exercise_update_attributes
}