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
我有 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