nuT707
nuT707

Reputation: 1573

Rspec, how to test method with multiple service calls?

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?

Upvotes: 1

Views: 1648

Answers (2)

BroiSatse
BroiSatse

Reputation: 44685

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.

Upvotes: 1

spickermann
spickermann

Reputation: 106882

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

Upvotes: 1

Related Questions