Home > Blockchain >  Rspec, how to test method with multiple service calls?
Rspec, how to test method with multiple service calls?

Time:01-27

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?

CodePudding user response:

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

CodePudding user response:

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.

  •  Tags:  
  • Related