Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expect_any_instance_of(…).not_to receive(…) makes a private instance method public #1584

Closed
manueljacob opened this issue Jul 23, 2024 · 1 comment · Fixed by #1596
Closed

Comments

@manueljacob
Copy link

manueljacob commented Jul 23, 2024

Subject of the issue

expect_any_instance_of(…).not_to receive(…) or expect_any_instance_of(…).to receive(…) make a private instance method public. expect(…).not_to receive(…) and expect(…).not_to receive(…) work as intended.

Your environment

  • Ruby versions: 2.3.8, 2.4.10, 2.5.9, 2.6.10, 2.7.8, 3.0.7, 3.1.6, 3.2.4, 3.3.4 (for the latter, the reproducer script has to be changed slightly to account for the changed NoMethodError message)
  • rspec-mocks version: 3.13.1

Steps to reproduce

Run the following script.

# frozen_string_literal: true

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.13.0" # Activate the gem and version you are reporting the issue against.
end

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

RSpec.describe 'a private method' do
  let(:klass) do
    Class.new do
      private

      def defined_private_method
      end
    end
  end

  let(:object) { klass.new }

  shared_examples 'behaves like a private method' do
    it 'can’t be called from the outside' do
      expect{object.defined_private_method}.to raise_error "private method `defined_private_method' called for #{object}"
    end

    it 'is included in the list of private methods' do
      expect(object.private_methods).to include :defined_private_method
    end

    it 'is not included in the list of public methods' do
      expect(object.public_methods).not_to include :defined_private_method
    end
  end

  context 'that is not mocked' do
    include_examples 'behaves like a private method'
  end

  context 'mocked with #expect' do
    before do
      expect(object).not_to receive(:defined_private_method)
    end

    include_examples 'behaves like a private method'
  end

  context 'mocked with #expect_any_instance_of' do
    before do
      expect_any_instance_of(klass).not_to receive(:defined_private_method)
    end

    include_examples 'behaves like a private method'
  end
end

Expected behavior

There should be no failures.

Actual behavior

All examples in context 'mocked with #expect_any_instance_of' fail.

@JonRowe
Copy link
Member

JonRowe commented Oct 2, 2024

Thanks for reporting this, apologies for the delay in looking at it but can you give #1596 a spin to see if it solves your issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants