Rspec expect(instance) to receive method not working as expected

8.1k views Asked by At
#controller file
def update
  @payment = Payment.find_by(reference_id: params[:reference_id])
  if @payment.update(update_params)
    @payment.do_something
  end
end

when trying to spec if do_something method was called, by

expect(@payment).to receive(:do_something)

it says

expected: 1 time with any arguments
received: 0 times with any arguments

do_something is in my Payment Class. It is actually being called, but rspec says not.

Any ideas? thanks in advance

2

There are 2 answers

2
Denis Romanovsky On

Your @payment in specs is actually a totally different variable, which is part of specs class, not the controller. I may be wrong, but that is my assumption from the parts of code you post - add specs code for more info. As of the solution, may use 'stub any instance'

Payment.any_instance.stub(:do_something).and_return(:smthing)

A more complicated approach - using doubles

2
Nimish Gupta On

Firstly you need to stub the lines in controller in order to expect some code

before do
  allow(Payment).to receive(:find_by).and_return(payment)
  allow(payment).to receive(:update).and_return(true)
  allow(payment).to receive(:do_something)
end

Also, instance variable in controller won't be directly accessible in rspecs.

So, First create a payment object in rspecs using let and use it before block like I did it in above solution