0

The RSpec documentation shows how to mock a class method. How can I replace an instance method instead. Here is a code example using rspec-mocks to make this more concrete:

require 'rspec'

class Foo
  def foo
    "foo"
  end

  def foobar
    foo + "bar"
  end
end

RSpec.describe "Foo" do
  it "mocks foo" do
    allow(Foo).to receive(:foo).and_return("bar")
    foo = Foo.new
    expect(foo.foobar).to eq("barbar")
  end
end

This gives "Foo does not implement: foo". Granted, this is contrived for simplification. In the actual class I'm testing, foo makes a HTTP request, so I want to mock it while writing a spec for foobar. I'd like to do this with rspec-mocks, but if another gem can help here, I'm open to that as well.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268

1 Answers1

1

Just stub the method on the instance instead of the class:

RSpec.describe "Foo" do
  it "mocks foo" do
    foo = Foo.new
    allow(foo).to receive(:foo).and_return("bar")
    expect(foo.foobar).to eq("barbar")
  end
end
spickermann
  • 100,941
  • 9
  • 101
  • 131
  • Thanks for the answer. I had tried this in my actual project and it didn't work. Now it dawned on me that it's because I'm calling the equivalent of `foo` in my example here from `initialize`. So maybe I need to rethink the design of my class. – Code-Apprentice Mar 03 '22 at 04:13