rspec-rails使用FactoryGirl发布单个参数

时间:2015-01-17 01:23:18

标签: ruby-on-rails rspec

FavoritesController#create只接受来自帖子请求的一个输入参数doctor_id

class FavoritesController < ApplicationController
  before_action :authenticate_user!
  def create
    @favorite = Favorite.new(favorite_params)
    @favorite.patient_id = current_user.id

    respond_to do |format|
      if @favorite.save!
        format.js
      else
        format.json { render json: @favorite.errors, status: :unprocessable_entity }
      end
    end
  end

  private
    def favorite_params
      params.require(:favorite).permit(:doctor_id)
    end
end

我有2个例子来测试它

describe FavoritesController do

  login_patient

  def valid_attributes
    FactoryGirl.attributes_for(:favorite, doctor_id: rand(1..1000))
  end

  describe "POST create" do
    describe "with valid params" do
      it "creates a new Favorite" do
        expect {
          post :create, favorite: valid_attributes, format: :js
        }.to change(Favorite, :count).by(1)
      end

      it "redirects to the created favorite" do
        post :create, favorite: valid_attributes, format: :js
        response.should render_template :create
      end
    end
  end
end

但我在参数

上出错了
1) FavoritesController POST create with valid params creates a new Favorite
   Failure/Error: post :create, favorite: valid_attributes, format: :js
   ActiveRecord::RecordInvalid:
     Validation failed: Doctor can't be empty
   # ./app/controllers/favorites_controller.rb:18:in `block in create'
   # ./app/controllers/favorites_controller.rb:17:in `create'
   # ./spec/controllers/favorite_controller_spec.rb:17:in `block (5 levels) in <top (required)>'
   # ./spec/controllers/favorite_controller_spec.rb:16:in `block (4 levels) in <top (required)>'

2) FavoritesController POST create with valid params redirects to the created favorite
   Failure/Error: post :create, favorite: valid_attributes, format: :js
   ActiveRecord::RecordInvalid:
     Validation failed: Doctor can't be empty
   # ./app/controllers/favorites_controller.rb:18:in `block in create'
   # ./app/controllers/favorites_controller.rb:17:in `create'
   # ./spec/controllers/favorite_controller_spec.rb:22:in `block (4 levels) in <top (required)>'

我相信我已经给出了控制器中定义的有效参数,但由于验证它似乎要求@doctor而不是doctor_id

class Favorite < ActiveRecord::Base
  belongs_to :doctor
  belongs_to :patient

  validates :doctor, :patient, presence: true
end

这是我的工厂

require 'faker'

FactoryGirl.define do
  factory :user do
    name = Faker::Name.name
    name name
    address Faker::Address.street_address
    phone Faker::PhoneNumber.phone_number
    password Faker::Internet.password
    sequence(:email) { |n| "#{name.split.join.downcase}_#{n}@example.com" }
  end

  factory :doctor, class: Doctor, parent: :user do
    roles [0,1]
    field
  end

  factory :patient, class: Patient, parent: :user do
    roles [1]
  end
end

有什么想法来解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

class Favorite < ActiveRecord::Base
  belongs_to :doctor
  belongs_to :patient

  validates :doctor, :patient, presence: true
end

当您尝试创建“收藏的医生”时,Favorite is belongs to doctor应该存在。

您收到此错误的原因是,当您尝试创建favorite时,它会查找您在数据库中传递的ID的状态doctor,并且您将random number作为doctor_id传递所以它fails validationdoctor record does not exist

您必须先create doctor record并将该医生记录的id传递给最喜欢的属性doctor_id

选项1: -

  def valid_attributes
    doctor = FactoryGirl.create(:doctor)
    FactoryGirl.attributes_for(:favorite, doctor_id: doctor.id)
  end

选项2: -

  def valid_attributes(doctor_id)
    FactoryGirl.attributes_for(:favorite, doctor_id: doctor_id)
  end

  let(:doctor) { create(:doctor) }
  describe "POST create" do
    describe "with valid params" do
      it "creates a new Favorite" do
        expect {
          post :create, favorite: valid_attributes(doctor.id), format: :js
        }.to change(Favorite, :count).by(1)
      end
    end
  end