Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

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

Closed
@manueljacob

Description

@manueljacob

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions