I'm trying to write a fairly straightforward test on a service object that handles an error. Rails version 5.2 and Rspec 3.8.
app/services/application_service.rb
class ApplicationService
def self.call(*args, &block)
new(*args, &block).call
end
end
app/services/basic_objects/create_payment.rb
module BasicObjects
class CreatePayment < ApplicationService
def initialize(args)
@transaction_id = args[:transaction_id]
end
def call
transaction = Transaction.find(@transaction_id)
payment = Payment.new(transaction: transaction)
payment.save
rescue CustomError => e
if /waiting/i === e.message
puts "Ignoring exception \"#{e.message}\" to prevent retry"
else
raise e
end
end
end
Here is the test
describe BasicObjects::CreatePayment, type: :model do
describe '#call' do
let(:params) { { transaction_id: "xyz" } }
context 'when there is a rescued error' do
before do
allow_any_instance_of(Payment)
.to receive(:save)
.and_raise(CustomError, "waiting")
end
it 'does not raise an error' do
expect { described_class.call(params) }.not_to raise_error
end
end
end
end
And it responds with this error:
expected no Exception, got #<ArgumentError: wrong number of arguments (given 1, expected 0)
But if I remove the params and instead expect(described_class.call).not_to raise_error
I get an error from not sending the argument
<BasicObjects::CreatePayment (class)> received :call with unexpected arguments
expected: ({:transaction_id=>"xyz"})
got: (no args)
So, then I remove with(params) from the allow statement
context 'when there is a rescued error' do
before do
allow(described_class).to receive(:call).and_raise(CustomError, "waiting")
end
it 'does not raise an error' do
expect(described_class.call).not_to raise_error
end
end
And I get
ArgumentError:
wrong number of arguments (given 1, expected 0)
Any help is greatly appreciated
UPDATE
I have adjusted the call above to raise the error on a line in the class, rather than just in calling the class itself. However, I am still getting the same error: expected no Exception, got #<ArgumentError: wrong number of arguments (given 1, expected 0)>
I ran into a similar problem and the <ArgumentError: wrong number of arguments (given 1, expected 0)> was very misleading and confusing.
Given your example, the problem is likely that your CustomError class's initialize method takes 0 argument and you are passing the "waiting" string as part of your mock, ie. allow_any_instance_of(Payment).to receive(:save).and_raise(CustomError, "waiting").
The error message is actually complaining that you are passing the wrong number of arguments in your exception as your mocked exception is raised. So this should be fixed by removing "waiting":
allow_any_instance_of(Payment)
.to receive(:save)
.and_raise(CustomError)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With