undefined method `ancestors' on PUT with rspec test
Asked Answered
M

3

9

i'm testing with rspec, factory_girl and capybara. The project uses devise, i have the following method to login inside the specs:

def login_admin
before(:each) do
  @request.env["devise.mapping"] = Devise.mappings[:admin]
  sign_in FactoryGirl.create(:admin)
end
end

def login_user
before(:each) do
  @request.env["devise.mapping"] = Devise.mappings[:user]
  sign_in FactoryGirl.create(:user)
end

end

Then i perform the tests on companies_controller_spec:

require 'spec_helper'

describe CompaniesController, :type => :controller do

let(:valid_attributes) { { "email" => Faker::Internet.email } }

login_admin

describe "GET show" do

  it "assigns the requested company as @company" do
    company = FactoryGirl.create(:company)
    get :show, {:id => company.to_param}
    expect(assigns(:company)).to eq(company)
  end
end

describe "GET edit" do
  it "assigns the requested company as @company" do
    company = FactoryGirl.create(:company)
    get :edit, {:id => company.to_param}
    expect(assigns(:company)).to eq(company)
  end
end

describe "PUT update" do
  describe "with valid params" do
    it "updates the requested company" do
      company = FactoryGirl.create(:company)
      expect_any_instance_of(company).to receive(:update).with({ "email" => "[email protected]" })
      put :update, {:id => company.to_param, :company => { "email" => "[email protected]" }}
    end
  end
end

But i keep getting this two errors:

NoMethodError:
   undefined method `ancestors' for #<Company:0x000000059b41f0>
# ./spec/controllers/companies_controller_spec.rb:34:in `block (4 levels) in <top (required)>' 
line 34: expect_any_instance_of(company).to receive(:update).with({ "email" => "[email protected]" })

and

expected: #<Company id: 86...
got: nil
# ./spec/controllers/companies_controller_spec.rb:41:in `block (4 levels) in <top (required)>'
line 41: expect(assigns(:company)).to eq(company)

This is my factory for companies:

FactoryGirl.define do
  factory :company do
    name { Faker::Name.name }
    plan_id {}
    phone { Faker::PhoneNumber.phone_number }
    email { Faker::Internet.email }
    facebook { Faker::Internet.url('facebook.com') }
    twitter { Faker::Internet.url('twitter.com') }
    linkedin { Faker::Internet.url('linkedin.com') }
    web { Faker::Internet.url }
 end
end
Misadvise answered 24/9, 2014 at 17:45 Comment(2)
Stack trace would be nice :)Internationalize
Added @KyleMacey! On main question.Misadvise
N
25

Just did this myself, accidentally called expect_any_instance_of on an actual instance, instead of on the class itself.

Old question, but for others finding this question, looks like OP should be using Company (uppercase class name) instead of company (lowercase reference to an instance).

expect_any_instance_of(Company).to receive(:update).with({ "email" => "[email protected]" })

To explain the error in a little more detail, ancestors is trying to access all of the classes from which Company inherits. A good example of ancestors/descendants on this other SO question.

Noted answered 3/12, 2015 at 0:44 Comment(2)
I'm using a little bit different stack (RSpec and Fabrication), but was getting the same error. I had called allow_any_instance_of on an object, not a class. This did it for me. Thx!Odin
This was the correct solution for my issue. I was using expect_any_instance_of with WhateverClass.new as the subject.Timeworn
K
0

Since you have company = FactoryGirl.create(:company), isn't company an instance on its own?

How about Company.any_instance.expects(:update).with({ "email" => "[email protected]" })?

Kakalina answered 24/9, 2014 at 20:28 Comment(0)
S
0

This is because we have to expect the actual modal/class -> here it is Company, instead of expecting any instance of the instance (company). so the expected line should be

expect_any_instance_of(Company) instead of expect_any_instance_of(company)

Scoutmaster answered 3/12, 2022 at 8:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.