Situation: I want to stub a helper method, so that I can call a method that wraps it and get the stubbed response back.
Code is set up like this:
class Thing
def self.method_one(foo)
self.method_two(foo, 'some random string')
end
def self.method_two(foo, bar)
self.method_three(foo, bar, 'no meaning')
end
def self.method_three(foo, bar, baz)
"#{foo} is #{bar} with #{baz}"
end
end
I'm trying to mock .method_three
so that I can call .method_one
and have it ultimately call .method_three
's double instead of the real deal:
it "uses the mock for .method_three" do
response_double = 'This is a different string'
thing = class_double("Thing", :method_three => response_double).as_stubbed_const
response = thing.method_one('Hi')
expect(response).to eq(response_double)
end
The error I'm getting:
RSpec::Mocks::MockExpectationError: #<ClassDouble(Thing) (anonymous)> received unexpected message :method_one with ("Hi")
Is what I'm trying to do possible? Feels like I'm missing an obvious step, but despite my best efforts I haven't been able to find an example of this or a question that asks anything comparable.
(Note: if it matters, this is not a Rails project.)
You may want to use RSpec's allow(...)
to stub the intermediate method. This is also useful for testing logic flow or for mocking third-party services in tests.
For example:
expected_response = 'This is a different string'
allow(Thing).to receive(:method_three).and_return(expected_response)
Then expect(Thing.method_one('Hi')).to eq(expected_response)
should pass.
See https://relishapp.com/rspec/rspec-mocks/v/2-14/docs/method-stubs for more information on stubbing methods.