I'm trying to test my API controller with RSPEC. The action in controller have a service that I want to stub/mock. But I got error :
Failure/Error: expect(Api::V1::PaymentsController).to
receive(:init_alias).and_return(svc)
Api::V1::PaymentsController does not implement: init_alias
Here my test :
let(:alias_svc) { instance_double(AliasService) }
describe 'POST /payment/card' do
it 'returns urls (return, success, fail)' do
expect(Api::V1::PaymentsController).to receive(:init_alias).and_return(alias_svc)
expect(alias_svc).to receive(:insert)
post '/payment/card'
end
end
And the controller :
module Api
module V1
class PaymentsController < ApiController
before_action :init_alias, only: [:register_card]
# POST /payment/card
def register_card
@url = @svc.insert current_user
end
private
def init_alias
@svc = AliasService.new
end
end
end
end
Edit :
I tried to delete the first line (expect(Api::V1::PaymentsController).to receive(:init_alias).and_return(alias_svc)) but I got
Failure/Error: expect(svc).to receive(:insert)
(InstanceDouble(AliasService) (anonymous)).insert(*(any args))
expected: 1 time with any arguments
received: 0 times with any arguments
Best Answer
Controller methods are instance methods. Therefore,
Api::V1::PaymentsController
does not implementinit_alias
.RSpec allows to use
expect_any_instance_of
:Edit
You send your message to
@svc
. Therefore, you should mock this instance variable to your controller.You can do something like this:
More details.