rspec / rspec-mocks

RSpec's 'test double' framework, with support for stubbing and mocking
https://rspec.info
MIT License
1.16k stars 357 forks source link

Assertion that Array#reverse is not called always fails #1532

Closed brtrick closed 1 year ago

brtrick commented 1 year ago

Subject of the issue

Any spec that includes expect_any_instance_of(Array).to_not receive(:reverse) will always fail because of internal RSpec calls.

Your environment

Steps to reproduce

Test that any method does not call Array#reverse. For example, test

def one
  1
end

with

it "should not call Array#reverse" do
    expect_any_instance_of(Array).to_not receive(:reverse)
    one
end

Expected behavior

Pass

Actual behavior

Failures:

  1) one should not call Array#reverse
     Failure/Error: DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure }

       ([]).reverse([])
           expected: 0 times with any arguments
           received: 1 time with arguments: ([])

The problem stems from the fact that the reset_all method that runs as part of the teardown_mocks_for_rspec cleanup calls Array#reverse in line 80, which triggers the recorder before it is cleared:

https://github.com/rspec/rspec-mocks/blob/5b5fded761651196070511076a3045748288b524/lib/rspec/mocks/space.rb#L78-L83

Clearing the recorders before executing line 80 would solve the problem. I've created a PR to that effect (#1533).