繁体   English   中英

使用嵌套属性在RSpec中测试POST #create-无法正确获取参数哈希

[英]Testing POST #create in RSpec with nested attributes - can't get params hash correct

已经花了几个月的时间尝试使用RSpec / TDD。 在测试带有嵌套属性的控制器时遇到一些挑战。 我对如何正确设置参数并将参数传递给控制器​​有点模糊。 我可以构建控制器,使其实际上可以在浏览器中正常工作-我似乎无法对测试进行反向工程来确认这一点。

感谢您提出以下建议:a)修复以下测试,以及b)建议采取任何更好的方法(例如,使用模拟,存根等)。

这是基本的模型结构:

class School < ActiveRecord::Base
  has_many :scholarships 
end

class Scholarship < ActiveRecord::Base
  belongs_to :school
end

我已经按照您的期望配置了route.rb:

  resources :schools do
    resources :scholarships, only: [:new, :create, :destroy]
  end

在控制器中,#new和#create是Rails应用程序的标准配置:

class ScholarshipsController < ApplicationController
  def new
    @school = School.find(params[:school_id])
    @scholarship = @school.scholarships.build
  end

  def create
    @school = School.find(params[:school_id])
    @scholarship = @school.scholarships.create(scholarship_params)
    if @scholarship.save
      flash[:success] = 'Scholarship created!'
      redirect_to @school
    else
      render 'new'
    end
  end

  private

    def scholarship_params
      params.require(:scholarship).permit(:name, ** Lots of params omitted for brevity **, 
        :notes, school: [:id])
    end
end

我似乎无法弄清规范。 对于spec / controllers / scholarships_controller_spec.rb:

require 'rails_helper'

describe ScholarshipsController, type: :controller do
  describe 'POST #create' do
    context 'with valid attributes' do
      before :each do
        @school = create(:school)
        @scholarship = @school.scholarships.create(FactoryGirl.build(:scholarship).attributes) 
      end

      it 'receives :save' do
        post :create, { scholarship: @scholarship.attributes, school: @school.id }
        expect(@scholarship).to receive(:save)
      end
    end
  end
end

运行该测试时,出现以下错误:

Failures:

  1) ScholarshipsController POST #create with valid attributes receives :save
     Failure/Error: post :create, scholarship: { attributes: @scholarship.attributes, school: @school.id }      #school_id: @school.id, scholarship: @scholarship
 ActionController::UrlGenerationError:
No route matches {:action=>"create", :controller=>"scholarships",
:scholarship=>{"id"=>"1", "name"=>"Dynamic Metrics Director Scholarship", *** Lots of parameters omitted for brevity ***
, "school_id"=>"2"}, :school=>"2"}

参数对我来说看起来正确。 奖学金和学校都有一套属性。 但是路由不起作用。 我尝试了十二种不同的方法来尝试使其正常工作。 令人鼓舞的是,我显然传递了(或多或少正确的)参数哈希,但无法弄清楚我要去哪里。

******编辑******

更新为响应下面发布的答案。 更改了Srdjan建议的规范语法:

 it 'receives :save' do
    post :create, "schools/#{@school.id}/scholarships", { scholarship: @scholarship.attributes, school_id: @school.id }
    expect(@scholarship).to receive(:save)
  end

这将更改错误消息。 我假设这表明参数已正确传递,因为它不再引发与路由/参数有关的错误。 错误信息是:

1) ScholarshipsController POST #create with valid attributes receives :save
     Failure/Error: expect(@scholarship).to receive(:save)
       (#<Scholarship:0x007fe293b02598>).save(*(any args))
           expected: 1 time with any arguments
           received: 0 times with any arguments

出于良好的考虑,以下是我之前未发布的相关路线:

  school_scholarships POST   /schools/:school_id/scholarships(.:format)     scholarships#create
new_school_scholarship GET    /schools/:school_id/scholarships/new(.:format) scholarships#new
    school_scholarship DELETE /schools/:school_id/scholarships/:id(.:format) scholarships#destroy

在测试中,您正在张贴错误的路线。 作为routes.rb设置,奖学金资源并不存在于学校资源的范围之外。

为了解决这个问题,您必须回答一个问题:“用户无需指定学校就可以访问奖学金记录吗?”

如果答案是肯定的,则您可以复制scholarships途径并将其粘贴到schools资源块之外。 这样,您无需指定学校,也可以指定学校而获得奖学金。

如果问题的答案为“否”,那么您需要像这样修复测试:

it 'receives :save' do post :create, "schools/#{@school.id}/scholarhips", { scholarship: @scholarship.attributes, school_id: @school.id } expect(@scholarship).to receive(:save) end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM