首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要帮助用嵌套资源排除RSpec控制器测试的故障

需要帮助用嵌套资源排除RSpec控制器测试的故障
EN

Stack Overflow用户
提问于 2015-02-08 21:23:59
回答 1查看 755关注 0票数 0

为了学习Rails和测试,我正在使用RSpec (v.3.1.0)、Capybara(2.4.3)和FactoryGirl构建一个Rails 4应用程序。在routes.rb中,我嵌套了以下资源以反映模型之间的关联:

代码语言:javascript
复制
resources :members do
  resources :cardio_exercises
end

members.rb包含: has_many :cardio_exercises,:dependent =>:=>

cardio_exercises.rb包含: belongs_to :belongs_to

FactoryGirl工厂用于cardio_exercises包含关联:成员

嵌套资源之后,我对视图和cardio_exercises_controller.rb进行了必要的更改:

代码语言:javascript
复制
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

我借助rake路由成功地更新了我的RSpec路由测试:

代码语言:javascript
复制
                 Prefix Verb   URI Pattern                                             Controller#Action
                   root GET    /                                                       static_pages#home
                  about GET    /about(.:format)                                        static_pages#about
                   help GET    /help(.:format)                                         static_pages#help
                contact GET    /contact(.:format)                                      static_pages#contact
                 signup GET    /signup(.:format)                                       users#new
                  login GET    /login(.:format)                                        sessions#new
                        POST   /login(.:format)                                        sessions#create
                 logout DELETE /logout(.:format)                                       sessions#destroy
                  users GET    /users(.:format)                                        users#index
                        POST   /users(.:format)                                        users#create
               new_user GET    /users/new(.:format)                                    users#new
              edit_user GET    /users/:id/edit(.:format)                               users#edit
                   user GET    /users/:id(.:format)                                    users#show
                        PATCH  /users/:id(.:format)                                    users#update
                        PUT    /users/:id(.:format)                                    users#update
                        DELETE /users/:id(.:format)                                    users#destroy
member_cardio_exercises GET    /members/:member_id/cardio_exercises(.:format)          cardio_exercises#index
                        POST   /members/:member_id/cardio_exercises(.:format)          cardio_exercises#create
new_member_cardio_exercise GET    /members/:member_id/cardio_exercises/new(.:format)      cardio_exercises#new
edit_member_cardio_exercise GET    /members/:member_id/cardio_exercises/:id/edit(.:format) cardio_exercises#edit
 member_cardio_exercise GET    /members/:member_id/cardio_exercises/:id(.:format)      cardio_exercises#show
                        PATCH  /members/:member_id/cardio_exercises/:id(.:format)      cardio_exercises#update
                        PUT    /members/:member_id/cardio_exercises/:id(.:format)      cardio_exercises#update
                        DELETE /members/:member_id/cardio_exercises/:id(.:format)      cardio_exercises#destroy
                members GET    /members(.:format)                                      members#index
                        POST   /members(.:format)                                      members#create
             new_member GET    /members/new(.:format)                                  members#new
            edit_member GET    /members/:id/edit(.:format)                             members#edit
                 member GET    /members/:id(.:format)                                  members#show
                        PATCH  /members/:id(.:format)                                  members#update
                        PUT    /members/:id(.:format)                                  members#update
                        DELETE /members/:id(.:format)                                  members#destroy
               trainers GET    /trainers(.:format)                                     trainers#index
                        POST   /trainers(.:format)                                     trainers#create
            new_trainer GET    /trainers/new(.:format)                                 trainers#new
           edit_trainer GET    /trainers/:id/edit(.:format)                            trainers#edit
                trainer GET    /trainers/:id(.:format)                                 trainers#show
                        PATCH  /trainers/:id(.:format)                                 trainers#update
                        PUT    /trainers/:id(.:format)                                 trainers#update
                        DELETE /trainers/:id(.:format)                                 trainers#destroy
     strength_exercises GET    /strength_exercises(.:format)                           strength_exercises#index
                        POST   /strength_exercises(.:format)                           strength_exercises#create
  new_strength_exercise GET    /strength_exercises/new(.:format)                       strength_exercises#new
 edit_strength_exercise GET    /strength_exercises/:id/edit(.:format)                  strength_exercises#edit
      strength_exercise GET    /strength_exercises/:id(.:format)                       strength_exercises#show
                        PATCH  /strength_exercises/:id(.:format)                       strength_exercises#update
                        PUT    /strength_exercises/:id(.:format)                       strength_exercises#update
                        DELETE /strength_exercises/:id(.:format)                       strength_exercises#destroy
           appointments GET    /appointments(.:format)                                 appointments#index
                        POST   /appointments(.:format)                                 appointments#create
        new_appointment GET    /appointments/new(.:format)                             appointments#new
       edit_appointment GET    /appointments/:id/edit(.:format)                        appointments#edit
            appointment GET    /appointments/:id(.:format)                             appointments#show
                        PATCH  /appointments/:id(.:format)                             appointments#update
                        PUT    /appointments/:id(.:format)                             appointments#update
                        DELETE /appointments/:id(.:format)                             appointments#destroy

我很难为嵌套资源编写控制器的测试。目前,“获取索引”和"POST create“(第一次it)的测试正在通过;其他测试正在失败。我的cardio_exercises_controller_spec.rb是不完整的,但我到目前为止拥有的是:

代码语言:javascript
复制
require 'rails_helper'

RSpec.describe CardioExercisesController, :type => :controller do
before :each do
  @member = FactoryGirl.create(:member)
  @cardio_exercise = FactoryGirl.create(:cardio_exercise)
  @cardio_exercise_attributes = FactoryGirl.attributes_for(: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.cardio_exercises)
  end
end

describe "GET show" do
  it "assigns the requested cardio_exercise as @member.cardio_exercise" do
    #@cardio_exercise = @member.cardio_exercises.find(params[:id])      
    get :show, { :member_id => @member, :cardio_exercise_id => @cardio_exercise }
    expect(assigns(:cardio_exercise)).to eq(@member.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(@member.cardio_exercise)
  end
end

describe "GET edit" do
  xit "assigns the requested cardio_exercise as @member.cardio_exercise" do 
  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

    xit "assigns a newly created cardio_exercise as @cardio_exercise" do
    end

    xit "redirects to the created cardio_exercise" do
    end
  end
end

describe "PUT update" do
    describe "with invalid params" do

    xit "updates the requested cardio_exercise" do

   end

   xit "assigns the requested cardio_exercise as @member.cardio_exercise" do

   end

    xit "redirects to the cardio_exercise" do
   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, :cardio_exercise_id => @cardio_exercise }
    }.to change(CardioExercise, :count).by(-1)
  end

  it "redirects to the cardio_exercises list" do      
    delete :destroy, { :member_id => @member, :cardio_exercise_id => @cardio_exercise }
    expect(response).to redirect_to(member_cardio_exercises_url)
  end
 end
end

运行规范不会产生路由匹配和未定义的方法错误:

代码语言:javascript
复制
1) CardioExercisesController GET show assigns the requested cardio_exercise as @member.cardio_exercise
 Failure/Error: get :show, { :member_id => @member, :cardio_exercise_id => @cardio_exercise }
 ActionController::UrlGenerationError:
   No route matches {:action=>"show", :cardio_exercise_id=>"15", :controller=>"cardio_exercises", :member_id=>"29"}

2) CardioExercisesController GET new assigns a new cardio_exercise as @member.cardio_exercise
 Failure/Error: expect(assigns(:cardio_exercise)).to be_a_new(@member.cardio_exercise)
 NoMethodError:
   undefined method `cardio_exercise' for #<Member:0x00000009aaa628>

3) CardioExercisesController DELETE destroy destroys the requested cardio_exercise
 Failure/Error: delete :destroy, { :member_id => @member, :cardio_exercise_id => @cardio_exercise }
 ActionController::UrlGenerationError:
   No route matches {:action=>"destroy", :cardio_exercise_id=>"18", :controller=>"cardio_exercises", :member_id=>"35"}

 4) CardioExercisesController DELETE destroy redirects to the cardio_exercises list
 Failure/Error: delete :destroy, { :member_id => @member, :cardio_exercise_id => @cardio_exercise }
 ActionController::UrlGenerationError:
   No route matches {:action=>"destroy", :cardio_exercise_id=>"19", :controller=>"cardio_exercises", :member_id=>"37"}

嵌套路由和相关的视图代码按照我的应用程序的预期工作。显然,我没有向RSpec提供测试我的控制器所需的所有信息。我知道我必须为某些测试传递I,但我对语法感到困惑。在我的研究中,我发现了许多讨论这个问题的帖子,但我没有什么可以解决的。

如何更改控制器测试以向RSpec提供它所需的信息?我很感激你的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-09 06:37:04

错误1、3和4是由于您的RSpec示例设置参数:cardio_exercise_id而不是必需的(根据您的路由) :id造成的。您传递的示例工作正常,因为它们不需要此参数。

错误2是由于has_many没有为关联定义单一访问方法(即定义了member.cardio_exercises,但没有定义member.cardio_exercise)。因为be_a_new只需要一个类,所以只需将CardioExercise作为参数传递即可。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28399522

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档