user2490003
user2490003

Reputation: 11890

Stubbing method parameters in RSpec

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

Answers (1)

Myron Marston
Myron Marston

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

Related Questions