Skip to content

Raise error when trying to use `have_received` without rspec-expectations

Created by: randycoulman

This is a workaround for #967 (closed). It doesn't actually fix the underlying bug, but does provide more documentation and an explanatory error message.

There are two commits:

  1. Add more documentation about the inability to use have_received without rspec-expectations
  2. Raise an explanatory error message when attempting to use have_received without rspec-expectations.

I couldn't find a way to add a spec for this new error, as all of the current specs run with rspec-expectations in place. If someone can suggest a way to test this properly, I'd be happy to do so.

Given this example code:

require "minitest/autorun"
require "rspec/mocks"

class User
  def accept_invitation(invitation)
    invitation.accept
  end
end

module RSpecMocksIntegration
  include ::RSpec::Mocks::ExampleMethods

  def before_setup
    ::RSpec::Mocks.setup
    super
  end

  def after_teardown
    super
    ::RSpec::Mocks.verify
  ensure
    ::RSpec::Mocks.teardown
  end
end

class SpyTest < Minitest::Test
  include RSpecMocksIntegration

  def test_accepts_invitation
    invitation = spy("invitation")
    user = User.new
    user.accept_invitation(invitation)
    expect(invitation).to have_received(:accept)
  end
end

the following error message occurs in the current version of rspec-mocks:

  1) Error:
SpyTest#test_accepts_invitation:
NoMethodError: undefined method `setup_expectation' for #<RSpec::Mocks::Matchers::HaveReceived:0x007fa764215800>
    /Users/randy/.rvm/gems/ruby-2.2.2/gems/rspec-mocks-3.3.0/lib/rspec/mocks/targets.rb:45:in `define_matcher'
    /Users/randy/.rvm/gems/ruby-2.2.2/gems/rspec-mocks-3.3.0/lib/rspec/mocks/targets.rb:14:in `block in delegate_to'
    bug_test.rb:33:in `test_accepts_invitation'

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

With the code from this PR, the following message occurs instead:

  1) Error:
SpyTest#test_accepts_invitation:
RSpec::Mocks::MockExpectationError: Using expect(...) with the `have_received` matcher is not supported when using rspec-mocks without rspec-expectations.
    /Users/randy/.rvm/gems/ruby-2.2.2/gems/rspec-support-3.3.0/lib/rspec/support.rb:86:in `block in <module:Support>'
    /Users/randy/.rvm/gems/ruby-2.2.2/gems/rspec-support-3.3.0/lib/rspec/support.rb:93:in `call'
    /Users/randy/.rvm/gems/ruby-2.2.2/gems/rspec-support-3.3.0/lib/rspec/support.rb:93:in `notify_failure'
    /Users/randy/src/github/rspec-mocks/lib/rspec/mocks/error_generator.rb:320:in `notify'
    /Users/randy/src/github/rspec-mocks/lib/rspec/mocks/error_generator.rb:304:in `__raise'
    /Users/randy/src/github/rspec-mocks/lib/rspec/mocks/error_generator.rb:193:in `raise_have_received_disallowed'
    /Users/randy/src/github/rspec-mocks/lib/rspec/mocks/matchers/have_received.rb:76:in `disallow'
    /Users/randy/src/github/rspec-mocks/lib/rspec/mocks/matchers/have_received.rb:62:in `setup_expectation'
    /Users/randy/src/github/rspec-mocks/lib/rspec/mocks/targets.rb:45:in `define_matcher'
    /Users/randy/src/github/rspec-mocks/lib/rspec/mocks/targets.rb:14:in `block in delegate_to'
    bug_test.rb:34:in `test_accepts_invitation'

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

If I instead require "rspec-expectations" and include RSpec::Matchers in the RSpecMocksIntegration module of my example, the tests pass as expected.

Merge request reports