Reputation: 11890
Suppose I have a class
class A
def initialize
end
def foo(a, b)
# Do stuff
end
end
When writing RSpec tests for this, how do I intercept the call to foo
and modify it's parameters?
I might try something like the following that catches the method call, yields the params so I can modify them, and then calls the original method
my_obj = A.new
allow(my_obj).to receive(:foo) do |a, b|
my_obj.foo("new", "values")
end
expect(my_obj.foo).to eq("bar")
However, the problem with this is that calling A#foo
inside the block once again stubs that and yields a new block, producing an infinite recursive loop until the stack runs out of memory.
I know that .and_call_original
method also exists, but can I yield the params with that and modify them before calling the original with the new modified params?
Or is there a way to "un-stub" the object inside the block so me calling it again doesn't cause a problem?
Thanks!
Upvotes: 0
Views: 1744
Reputation: 21800
Use and_wrap_original
:
my_obj = A.new
allow(my_obj).to receive(:foo).and_wrap_original do |original_method, a, b|
original_method.call("new", "values")
end
expect(my_obj.foo).to eq("bar")
Upvotes: 5