-
-
Notifications
You must be signed in to change notification settings - Fork 358
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
and_call_original does not always properly restore the method #613
Comments
This reverts commit 1daa021. Currently `allow(obj).to receive(:message).and_call_original` does not work as well as `unstub` sometimes. rspec/rspec-mocks#613
I've found the same issue while implementing the conversion of
You can reproduce this with the following steps: $ git clone https://github.com/yujinakayama/transpec.git
$ cd transpec
$ git checkout support-conversion-of-unstub
$ bundle install
$ bundle exec rake test:guard The |
Thanks, @yujinakayama. I've updated the labels on this from "not a release blocker" to "release blocker" since I think it's important that we get this to work so transpec can convert. |
I am looking at this. |
Ok there are some serious dragons here. First Dragon Those guard specs are actually relying on When using unstub, caller is shallow:
When using
So the original method is being called fine, but since the backtrace is different it is causing spec failures. Second Dragon Replacing methods in a class hierarchy acts really weird. class A
M = A.method(:new)
def self.new
M.call
end
end
class B < A; end
puts B.new # #<A:0x007f9bd408d438> @myronmarston what was the initial motivation for replacing To fix at least the first issue above, My current recommendation is that transpec not perform an automatic conversion from |
There was never an intentional plan to replace Later on, in #486, I realized that
What is the different meaning in your head? Anyhow...this is all say I'm not sure what the right thing to do here is. I agree that the guard |
BTW, @xaviershay, did you take a look at the pending examples for this? Those are cases where |
the first one I looked and at don't know how to solve (that's the second dragon). The |
I took a look at this and started building a model of what's going on in my head. It's something to do with the original method being captured incorrectly on subclasses when both classes are already stubbed. |
So I've started digging into this and now I understand what's going on. With normal (e.g. not class) objects, when we define a singleton method on that object, that object is the only object affected. The only previously stubs that could affect that object are stubs on the object itself that the Classes are different: when you define a singleton method on it, it affects subclasses, too, due to how ruby's method lookup works with classes. So here's what's going on: it "restores the correct implementations when stubbed and unstubbed on a parent and child class" do
parent = stub_const("Parent", Class.new)
child = stub_const("Child", Class.new(parent))
allow(parent).to receive(:new)
allow(child).to receive(:new)
allow(parent).to receive(:new).and_call_original
allow(child).to receive(:new).and_call_original
expect(parent.new).to be_an_instance_of parent
expect(child.new).to be_an_instance_of child
end The parent's I'm working on a fix. It's tricky but not insurmountable. |
Sounds similar to the prepend issue... |
I'm going to take a look at the |
So it turns out that the failing it "can change how instances responds in the middle of an example" do
instance = klass.new
allow_any_instance_of(klass).to receive(:foo).and_return(1)
expect(instance.foo).to eq(1)
allow_any_instance_of(klass).to receive(:foo).and_return(2)
expect(instance.foo).to eq(2)
end fails with:
I'm working on a fix for this. @yujinakayama, I think it's safe to make transpec convert to |
👍 |
@myronmarston Thanks! 👍 |
Closing in favor of #651. |
See: rspec/rspec-mocks#613 (comment) This closes #49.
I discovered this while working on #612, when I migrated some specs from using
unstub
to usingand_call_original
. I marked the ones that failed aspending
:The text was updated successfully, but these errors were encountered: