Class structure:
class Service1
def foo
puts 'foo'
end
end
class Service2
def bar
3.times.each do
Service1.new().foo
end
end
end
I want to test that bar method of Service2 is called 3 times.
How to do it best in rspec3?
I would refactor the code to:
class Service1
def self.foo
new.foo
end
def foo
puts 'foo'
end
end
class Service2
def bar
3.times.each do
Service1.foo
end
end
end
And would then use a spec like this
describe "#bar" do
let(:service1) { class_double("Service1") }
it "calls Service1.foo three times" do
expect(service1).to receive(:foo).exactly(3).times
Service2.bar
end
end
You can achieve this by mocking new method
class Service1
def foo
puts 'foo'
end
end
class Service2
def bar
3.times.each do
Service1.new().foo
end
end
end
Then the test:
let(:mocked_service) { instance_spy Service1 }
it "calls Service1.foo three times" do
allow(Service1).to receive(:new).and_return mocked_service
Service2.bar
expect(mocked_service).to have_received(:foo).exactly(3).times
end
However, as mentioned in the comment - the necessity of using mocks is a first sign of flawed OO design, meaning that the problem you posted is merely a symptom. Refer to SOLID principles to find better design.