rspec-rails post 单参数与 FactoryGirl

rspec-rails post single param with FactoryGirl

我有 FavoritesController#create,它只接受来自 post 请求的一个输入参数 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

有解决办法吗?

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

  validates :doctor, :patient, presence: true
end

因为 Favorite is belongs to doctor 当您尝试创建 Favorite Doctor 之前应该存在。

您收到此错误是因为当您尝试创建 favorite 时,它会查找存在 doctor 以及您在数据库中传递的 ID,并且您将 random number 作为 doctor_id 所以它 fails validation 作为 doctor 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