Skip to content

and_return broken on implicit (self) receiver stubs

gitlab-qa-bot requested to merge fix_implicit_stub! into 2-14-maintenance

Created by: JonRowe

RSpec 2.13 supported implicit receivers inside describes. For example, instead of doing obj.stub!(...), you could do self.stub!(...) (or just stub!(...)), where self is the context of the it block. This was not a common usage, but it is extremely useful for testing modules with private features. You could include Foo into your context and use it from the spec. This no longer works in 2.14.

Minimal reproduction:

require 'rspec'

describe 'implicit mocks' do
  it 'accepts and_return on an implicit mock' do
    stub!(:foo).and_return('bar')
    expect(foo).to eq('bar')
  end
end

Output:

~/spec$ rspec foo_spec.rb 
F

Failures:

  1) implicit mocks accepts and_return on an implicit mock
     Failure/Error: stub!(:foo).and_return('bar')
       Stub :foo received unexpected message :and_return with ("bar")
     # ./foo_spec.rb:5:in `block (2 levels) in <top (required)>'

A more complete usage scenario might be:

require 'rspec'

module Foo
  private # these methods are not callable from outside
  def foo; bar end
  def bar; 0 end
end

describe Foo do
  include Foo

  describe '#foo' do
    it 'returns the result of #bar' do
      stub!(:bar).and_return(42)
      expect(foo).to eq(42)
    end
  end
end

If this will not be supported in 3.x, are there any suggestions on how to not rely on implicit receivers for these tests?

Merge request reports