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

Fixing an issue with a spoiling of the object singleton classes #891

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

alekseyl
Copy link

.stub method defined in minitest/mock executing an alias_method against singleton_class under the hood.
Running an alias_method over a singleton_class without running a 'remove_method' later will keep singleton_class 'dirty' and running undef_method might clear more than needed.

Usually this will not lead to any consequences, but if you are stubbing methods of a global objects and trying to enrich functionality of their ancestors chain 'after' the the first stubbing is done, then you might fall into trouble.

Even though the probability for such a case is tiny, it's not 0 and singleton class should be kept clean.

…initions.

This could lead to real issues with the global objects like classes, class variables e.t.c.
…stubbing class method, then it's defined on the class singleton_class, and should be kept.
alekseyl added a commit to alekseyl/stubberry that referenced this pull request Jan 18, 2022
* new module with assertion methods added
* assert_method_called added, this is a flow assertion, you can check the params, and you can check that method was called inside the block,
  without stubbing objects and interfering with the original flow
* minimal ruby version set to 2.5 ( so we can replace indirect invocations via send(:*_method ) to direct invocations )
* singleton_classes is now properly cleared after, see PR: minitest/minitest#891
* some methods got '__' prefixes, just to prevent naming collisions
Copy link

@luke-gru luke-gru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about when you're stubbing a singleton class method instead of an instance method? This would erase the method on the singleton class, unless I'm reading it wrong.

@GermanDZ
Copy link

What about when you're stubbing a singleton class method instead of an instance method? This would erase the method on the singleton class, unless I'm reading it wrong.

Also consider these other cases: #811

@alekseyl
Copy link
Author

What about when you're stubbing a singleton class method instead of an instance method? This would erase the method on the singleton class, unless I'm reading it wrong.

hm, what about the testcase in the PR:

def test_class_singleton_class_will_not_loose_its_method
    _class = Class.new do
      def self.clean; :dirty end
    end

    _class.stub(:clean, :clean) do |s|
      assert_equal( s.clean, :clean )
    end
    # method is still present and unchanged
    assert_equal( _class.clean, :dirty )
  end

Looks like its covering your concern

@alekseyl alekseyl requested a review from luke-gru April 23, 2023 06:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants