rspec / rspec-mocks

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

Stubbing base class constructor gives uninuititive return value #1475

Closed skatenerd closed 2 years ago

skatenerd commented 2 years ago

Subject of the issue

Stubbing base-class constructor gives unintuitive behavior

Your environment

Steps to reproduce

begin
  require "bundler/inline"
rescue LoadError => e
  $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
  raise e
end

gemfile(true) do
  source "https://rubygems.org"

  gem "rspec", "3.7.0" # Activate the gem and version you are reporting the issue against.
end

puts "Ruby version is: #{RUBY_VERSION}"
require 'rspec/autorun'

module EdgeCase
  class Base
    def go
      'base'
    end
  end

  class Specific < Base
    def go
      'specific!'
    end
  end
end

RSpec.describe 'stubbing base class constructor' do
  it 'allows you to construct a subclass' do
    allow(EdgeCase::Base).to receive(:new).and_call_original
    thing = EdgeCase::Specific.new
    expect(thing).to be_a(EdgeCase::Specific)
  end
end

Expected behavior

Constructing the subclass gives you an instance of the subclass, rather than an instance of the base class (the test should pass)

Actual behavior

The test fails because thing is an instance of the base class. expected #<EdgeCase::Base:0x00007fc8db935a20> to be a kind of EdgeCase::Specific

pirj commented 2 years ago

There is an interesting discussion in a sibling ticket. Does it sound similar to your case?

skatenerd commented 2 years ago

Yeah, I'll close this one