0
votes

When testing my controller I have a spec in Rspec using factorygirl for the data;

describe 'POST #create' do
  context 'with valid attributes' do
    it 'saves the new child in the database' do
        expect{
          post '/children', :create, person: attributes_for(:child)
      }.to change(Person, :count).by(1)
    end

I get an error

1) PeopleController POST #create with valid attributes saves the new child in the database Failure/Error: post '/children', :create, person: attributes_for(:child) NoMethodError: undefined method key?' for :create:Symbol # ./spec/controllers/people_controller_spec.rb:46:inblock (5 levels) in ' # ./spec/controllers/people_controller_spec.rb:45:in `block (4 levels) in '

My controller(this is everything so sorry about the irrelevant stuff)

class PeopleController < ApplicationController
before_action :set_person, only: [:show, :edit, :update, :destroy]
before_action :set_type

def full_name
    [Person.christian_name, Person.surname].join ' '
end

def index
  @people = type_class.all
end

def new
    @person = type_class.new
end

def update
end

def show
end

def edit
end

def create
    if @person_type == 'Child'
    @person = Child.new(person_params)
    else
        @person = CareGiver.new(person_params)
    end
    if @person.save
        redirect_to @person
    else
        render 'new'
    end
end

def destroy
end

private

    def person_params
        if @person_type == 'Child'
            params.require(:child).permit(:type, :christian_name, :surname, :dob, :gender)
        else
            params.require(:care_giver).permit(:type, :christian_name, :surname, :email,
                                           :password, :password_confirmation)

        end

    end

    def set_type
        @person_type = type
    end

    def type
        Person.types.include?(params[:type]) ? params[:type] : "Person"
    end

    def people_types
        %w[Person Child Provider CareGiver]
    end

    def type_class
        type.constantize if type.in? people_types
    end

    def set_person
        @person = type_class.find(params[:id])
    end
end

This is saving different types of person to a single table (sti). It seems as though no params are passed to the controller. When I use debugger at this point I can create a Child object, but post doesn't pass it on. I added '/children' to get the correct route (although I read that rspec controller tests bypass the routes stack) I have stared at it for hours and have that feeling in my stomach you get from not knowing why! Thanks for any help

1
replace post '/children', :create with post :createapneadiving
I then get;Failure/Error: post :create, person: attributes_for(:child) ActionController::ParameterMissing: param is missing or the value is empty: care_giver, the wrong person type. Not sure why an empty care_giver hash turns up at the controller.leonormes
because its required in your person_params method, meaning test is reaching your controller nowapneadiving
The value that is missing, care_giver, should be child. Why is it turning up as care_giver(another type of person)leonormes

1 Answers

0
votes
  def set_type
    @person_type = type
end

def type
    Person.types.include?(params[:type]) ? params[:type] : "Person"
end

Found this code in my controller. the type method is not setting a value that @person_type could use. I got rid of method type, and change set_type to

def set_type
        @person_type = params[:person][:type]
    end

Not sure if this is safe? but now the test passes. p.s. All the other tests broke!!