Why do I get an undefined method 'have' error when running Rspec?
Asked Answered
P

3

25

I recently upgraded to Rails 4 and everything works fine except for my Rspec tests.

require 'spec_helper'

describe Invoice do

  before :each do
    @user = FactoryGirl.create(:activated_user)
    person = FactoryGirl.create(:person, :user => @user, :company => nil)
    @project = FactoryGirl.create(:project, :user => @user, :person_ids => [person.id], :invoice_recipient_id => person.id)
  end

  it "has a valid factory" do
    expect(FactoryGirl.build(:invoice, :project => @project, :user => @user)).to be_valid
  end

  it "is invalid without a number" do
    expect(FactoryGirl.build(:invoice, :project => @project, :user => @user, :number => nil)).to have(1).errors_on(:number)
  end

end

When running these tests I get this error:

Failure/Error: expect(FactoryGirl.build(:invoice, :project => @project, :user => @user, :number => nil)).to have(1).errors_on(:number)
NoMethodError:
undefined method `have' for #<RSpec::ExampleGroups::Invoice_2:0x009ge29360d910>
# ./spec/models/invoice_spec.rb:16:in `block (2 levels) in <top (required)>'

Can anybody tell me what I am missing here?

I googled it already but nothing came up. The have method is actually fairly standard in Rspec and I can't see why it shouldn't work.

Thanks for any pointers.

Postglacial answered 5/12, 2013 at 17:25 Comment(7)
Try passing a block to expect and not an instance (i.e., expect { })Homonym
Thanks but that doesn't change anything. Still getting the same error.Postglacial
@PeterAlfvin: OK, posted some more details above.Postglacial
As for me everything is correct (exactly as official examples). If I were you I would try to check this case expect(Invoice.new).to have... (use your class instead of Factory - do you have the same error?). Then try to check version and maybe update gem rspec-rails. Another idea: do you use spork, zeus or smth like this? Maybe smth is wrong in spec_helper.rbAbebi
@PeterAlfvin: Sorry about that, just removed the first two lines. Now it looks exactly like in my app.Postglacial
I just ran rails g rspec:install again to update my spec_helper.rb file. Then tried expect(Invoice.new).to have(1).errors_on(:number). But it gives me the exact same error as before.Postglacial
OK, solved and posted below. Thanks for your help!Postglacial
E
49

The have family of matchers was deprecated in RSpec 2.99 and has been moved to a separate rspec-collection_matchers gem as of RSpec 3.0. This is discussed in https://rspec.info/blog/2013/11/rspec-2-99-and-3-0-betas-have-been-released/, which also gives the suggested approach to migrating to 3.0. Specifically, it recommends installing/using RSpec 2.99 in order to see the deprecation messages associated with items that were removed/moved in 3.0.

Earthstar answered 5/12, 2013 at 23:46 Comment(4)
Ah thank you very much, Peter! Strange that I was unable to find this myself. I will mark your answer as the correct one.Postglacial
And thank you for reporting your problem. It turns out the removal in 3.00 was mistakenly omitted from the 3.0 beta 1 change log. After reporting it, they made a retroactive update to that section, per github.com/rspec/rspec-expectations/commit/…Earthstar
why do they separate it? Is it not recommended not use "have"?Levitate
The primary maintainer felt they were confusing, as he discussed in myronmars.to/n/dev-blog/2013/07/…Earthstar
S
5

In the latest versions of rspec "have" being deprecated, but you still can use it via rspec-collection_matchers gem.

# Gemfile
...
gem 'rspec-collection_matchers', group: :test
...

# spec/spec_helper.rb
...
require 'rspec/collection_matchers'
....
Swadeshi answered 11/3, 2018 at 11:14 Comment(0)
P
1

OK, got it.

I had the wrong version number in my Gemfile.

Before:

gem 'rspec-rails', '~> 3.0.0.beta'

After:

gem 'rspec-rails'
Postglacial answered 5/12, 2013 at 20:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.