使用rspec测试在PUT上使用未定义的方法"祖先"

nto*_*ier 5 rspec ruby-on-rails devise factory-bot

我正在测试rspec,factory_girl和capybara.该项目使用devise,我有以下方法登录规范:

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
Run Code Online (Sandbox Code Playgroud)

然后我在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
Run Code Online (Sandbox Code Playgroud)

但我一直得到这两个错误:

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" })
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

这是我公司的工厂:

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
Run Code Online (Sandbox Code Playgroud)

Jor*_*sen 14

我自己做了这件事,意外地调用expect_any_instance_of了一个实际的实例,而不是在类本身上.

老问题,但对于其他人发现这个问题,看起来OP应该使用Company(大写类名)而不是company(小写引用实例).

expect_any_instance_of(Company).to receive(:update).with({ "email" => "r@gmail.com" })

为了更详细地解释错误,ancestors尝试访问Company继承的所有类.在另一个SO问题上,祖先/后代的一个很好的例子.


seb*_*kom 0

既然你有,那么它本身company = FactoryGirl.create(:company)不是一个实例吗?company

怎么样Company.any_instance.expects(:update).with({ "email" => "r@gmail.com" })