spondbob
spondbob

Reputation: 1633

rspec-rails post single param with FactoryGirl

I have FavoritesController#create which only accepts one input param, doctor_id, from post request.

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

And I got 2 examples to test it

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

But I got error on the parameter

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)>'

I believe I've given valid params as defined in controller, but due to the validation it looks like it is asking for @doctor instead of doctor_id

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

  validates :doctor, :patient, presence: true
end

and here is my Factory

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

any idea to resolve this?

Upvotes: 0

Views: 77

Answers (1)

Sampat Badhe
Sampat Badhe

Reputation: 9075

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

  validates :doctor, :patient, presence: true
end

As Favorite is belongs to doctor when you are trying to create Favorite Doctor should exist before.

You are getting this error due to as your trying to create favorite it looks for the presence doctor with id that you passed in DB and you passed random number as doctor_id so it fails validation as doctor record does not exist.

You have to create doctor record first and pass the id of that doctor record to doctor_id of favorite attributes.

option 1:-

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

option 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

Upvotes: 1

Related Questions