emd
emd

Reputation: 13

FactoryGirl ArgumentError: wrong number of arguments (given 1, expected 0)

I'm running tests for a rails' controller and I'm finding some weird behavior. While in one of the rspec test file for another controller both methods from FactoryGirl (build, create) work as expected, this new test file is raising an ArgumentError: wrong number of arguments (given 1, expected 0) whenever I call the create method.

This is how the files look like:

describe DoctorsController, type: :controller do                                                   
  let(:user) { create(:user) }                                         

I'm using devise btw

This is how the FactoryGirl definition looks like:

require 'faker'

FactoryGirl.define do
  factory :user do
    email { Faker::Internet.email }
    password "password"
    password_confirmation "password"
  end
end

Same line in a different controller works like a charm:

describe ClinicsController, type: :controller do

  context 'when signed in' do
    let(:clinic) { build(:clinic) }
    let(:user) { create(:user) }
    before(:each) { sign_in user }

Any idea why this is happening? Thanks in advance

Complete example:

require 'rails_helper'

describe DoctorsController, type: :controller do
  let(:doctor) { build(:doctor) }
  let(:params) { doctor.attributes }
  let(:user) { create(:user) }

  it 'should be an instance of a secure controller' do
    expect(DoctorsController.new).to be_a(SecureApplicationController)
  end

  describe '#create' do
    subject(:create) { post :create, doctor: params }
    context 'when signed in' do
      before(:each) { sign_in user }

      context 'on success' do
        it 'should redirect with notification' do
          expect(create).to redirect_to(doctors_path)
          expect(flash[:notice]).to eq('Doctor creado satisfactoriamente')
        end
        it 'should create a new doctor' do
          expect{ create }.to change { Doctor.count }.by(1)
        end
        it 'should assign existing clinics when creating a doctor' do
          clinics = [create(:clinic), create(:clinic)]
          post :create, doctor: params, clinics: clinics.map(&:id)
        end
      end

      context 'on failure' do
        subject(:create) { post :create,
                           doctor: attributes_for(:doctor, name: nil) }
        it 'should redirect with notification' do
          expect(create).to redirect_to(new_doctor_path)
          expect(flash[:notice]).to eq('Error creando el doctor')
        end
      end
    end
  end
end

Stacktrace:

Failures:

  1) DoctorsController#create when signed in on success should redirect with notification
     Failure/Error: let(:user) { create(:user) }

     ArgumentError:
       wrong number of arguments (given 1, expected 0)
     # ./spec/controllers/doctors_controller_spec.rb:6:in `block (2 levels) in <top (required)>'
     # ./spec/controllers/doctors_controller_spec.rb:17:in `block (4 levels) in <top (required)>'

  2) DoctorsController#create when signed in on success should create a new doctor
     Failure/Error: let(:user) { create(:user) }

     ArgumentError:
       wrong number of arguments (given 1, expected 0)
     # ./spec/controllers/doctors_controller_spec.rb:6:in `block (2 levels) in <top (required)>'
     # ./spec/controllers/doctors_controller_spec.rb:17:in `block (4 levels) in <top (required)>'

  3) DoctorsController#create when signed in on success should assign existing clinics when creating a doctor
     Failure/Error: let(:user) { create(:user) }

     ArgumentError:
       wrong number of arguments (given 1, expected 0)
     # ./spec/controllers/doctors_controller_spec.rb:6:in `block (2 levels) in <top (required)>'
     # ./spec/controllers/doctors_controller_spec.rb:17:in `block (4 levels) in <top (required)>'

  4) DoctorsController#create when signed in on failure should redirect with notification
     Failure/Error: let(:user) { create(:user) }

     ArgumentError:
       wrong number of arguments (given 1, expected 0)
     # ./spec/controllers/doctors_controller_spec.rb:6:in `block (2 levels) in <top (required)>'
     # ./spec/controllers/doctors_controller_spec.rb:17:in `block (4 levels) in <top (required)>'

Finished in 0.0092 seconds (files took 5.95 seconds to load)
5 examples, 4 failures

Upvotes: 1

Views: 2473

Answers (1)

Greg
Greg

Reputation: 6650

It looks like you've overwritten create with

subject(:create) 

and it's not pointing to FactoryGirl.create anymore, now create evaluates the subject which is not expecting any params.

you can define subject with a different name, or even without any and do

   subject { post :create ...} 
   expect(subject).to ...

Upvotes: 3

Related Questions