Permalink
Browse files

Seems like Im running afould of method_double and the mock_proxy somehow

  • Loading branch information...
1 parent e2df799 commit 34ae8408089c485ce005675e385cc3e05f6c8c68 @kaiwren kaiwren committed Sep 1, 2010
Showing with 3 additions and 2 deletions.
  1. +3 −2 lib/rspec/mocks/any_instance.rb
@@ -50,8 +50,9 @@ def any_instance
def rspec_reset
@__recorder = nil
- __undecorate_new! if respond_to?(:__new_without_any_instance__)
- super
+ response = super
+ __undecorate_new! if __send__(:methods).include?(:__new_without_any_instance__)
@kaiwren

kaiwren Sep 1, 2010

Owner

I'm not sure why using #methods.include? instead of #respond_to? fixes the "restores the class to its original state after each example" spec, but only on 1.9.2 - it still fails on 1.8.7.

+ response
end
def reset?

4 comments on commit 34ae840

Why not just use the framework to manage all of this? Something like:

def any_instance
  stub(:new) do
    # ...
  end
end

That way the framework will restore the new method at the end of the example using already existing machinery.

Owner

kaiwren replied Sep 1, 2010

If I'm understanding this right, we'd need to be able to create a new functioning instance using every time new is invoked, so you'd have to be able to do something like

def any_instance
  stub(:new) do |*args, &block|
    # invoke original unstubbed new with *args, &block
    # stub resulting instance using messages recorded by the recorder
  end
  __recorder
end

Wouldn't this also fail on 1.8.7 in cases where new takes a block?
Is there anything I'm missing? (and my apologies for being this slow on the uptake)

Take a look at http://github.com/rspec/rspec-mocks/commit/62e1abfe613ff33b53c771be3cdc651545047d85

That's just a spike to demonstrate - there are no specs to show new() gets reset, but you get the idea.

Also - I noticed that this approach doesn't work with String.any_instance, for example. I'm not sure how mocha handles this, but it does work with String so you might want to take a peek at that.

Owner

kaiwren replied Sep 2, 2010

So it looks like "", [], {} and class bypass String.new, Array.new, Hash.new and Class.new respectively for performance reasons and the parser of course doesn't expose any hooks for us to latch onto except in rbx. I knew this about Class.new but it didn't strike me until you pointed out that doing String.any_instance doesn't affect strings created with "".

Seems like a deal breaker - I'll have to rethink the implementation so that it doesn't hinge on new. I've got some ideas from mocha, so I'll take another shot at it.

Please sign in to comment.