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" => "r@gmail.com" })
      put :update, {:id => company.to_param, :company => { "email" => "r@gmail.com" }}
    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" => "r@gmail.com" })

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
ntonnelier
  • 1,539
  • 3
  • 23
  • 49

3 Answers3

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" => "r@gmail.com" })

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.

Community
  • 1
  • 1
Jordan Arnesen
  • 413
  • 5
  • 10
  • 1
    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! – JT. Jan 26 '16 at 00:40
  • 1
    This was the correct solution for my issue. I was using `expect_any_instance_of` with `WhateverClass.new` as the subject. – dannypaz Apr 04 '16 at 14:11
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" => "r@gmail.com" })?

sebkkom
  • 1,426
  • 17
  • 31
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)

jansha
  • 164
  • 1
  • 8