WhyAyala
WhyAyala

Reputation: 675

Why are my tests telling me "param is missing or the value is empty:"?

Using Rails 4.2, rspec 2.14, rspec-rails 2.14, faker and factory-girls-rails gems

I have a model called Appointment that I'm running some tests on and everything passes except for the #create under the controller spec.

The error message I get is:

Failure/Error: post :create, FactoryGirl.attributes_for(:appointment) ActionController::ParameterMissing: param is missing or the value is empty: appointment

The Appointment model validates the presence of an association to an object called Service.

Here is my factory for appointment.rb:

require 'faker'

FactoryGirl.define do 
    factory :appointment do |f|
        f.service {FactoryGirl.create(:service)} 
        f.appointment_time { Faker::Time.between(DateTime.now - 1, DateTime.now) }
    end
end

Here is my appointment_spec.rb:

require 'spec_helper'

describe Appointment do

    it "has a valid factory" do
        FactoryGirl.create(:appointment).should be_valid
    end

    it "is invalid if it does not have a Service association" do
        FactoryGirl.build(
            :appointment, service: nil).should_not be_valid
    end

end

I've been following the instructions listed here for making my Controller Spec. I've also found a lot of stackoverflow posts that say to do the same thing, yet I still get the same error.

Here are the tests not passing from my appointment_controller_spec.rb

describe AppointmentsController do

 #other controller action code...

    describe "POST #create" do
        context "with valid attributes" do
            it "saves the new appointment in the database" do
                expect {
                    post :create, FactoryGirl.attributes_for(:appointment)
                }.to change(Appointment, :count).by(1)
            end

            it "redirects to show page" do
                post :create, FactoryGirl.attributes_for(:appointment)
                response.should redirect_to Appointment.last
            end
        end
end

I'm at a loss and hoping some one can offer some insight.

EDIT:

As some of you had recommended, I changed the controller spec. This is actually what I had before I changed my code to what you see above:

    it "saves the new appointment in the database" do
        expect {
            post :create, appointment:  FactoryGirl.attributes_for(:appointment)
        }.to change(Appointment, :count).by(1)
    end

The reason I changed this is because when I had this my original error message was:

Failure/Error: expect { count should have been changed by 1, but was changed by 0

Sorry for the confusion.

Upvotes: 0

Views: 475

Answers (2)

mccalljt
mccalljt

Reputation: 796

Are you using strong_params in your controller? It looks like you are looking for an appointment param, but you are just getting a hash of the attributes.

Try this:

    it "saves the new appointment in the database" do
        expect {
            post :create, appointment: FactoryGirl.attributes_for(:appointment)
        }.to change(Appointment, :count).by(1)
    end

Upvotes: 1

craig.kaminsky
craig.kaminsky

Reputation: 5598

I believe you just need your AppointmentsController spec to read as follows:

 describe AppointmentsController do

 #other controller action code...

    describe "POST #create" do
        context "with valid attributes" do
            it "saves the new appointment in the database" do
                expect {
                    post :create, appointment:  FactoryGirl.attributes_for(:appointment)
                }.to change(Appointment, :count).by(1)
            end

            it "redirects to show page" do
                post :create, appointment: FactoryGirl.attributes_for(:appointment)
                response.should redirect_to Appointment.last
            end
        end
end

Adding appointment: before you supply the attributes via FactoryGirl in the post call.

Upvotes: 2

Related Questions