Michael Michael - 6 months ago 15
Ruby Question

How to test error handling with RSpec?

I try to test this code:

mail = Mail.new
mail.from = @from
mail.to = to
<...>
begin
mail.deliver
rescue
return false
else
return true
end


for error handling with RSpec:

it 'should return true if success' do
expect(mailer.send_confirmation_request(token)).to be true
end

it 'should return false if fails' do
allow_any_instance_of(Mail).to receive(:deliver).and_raise('Mail error')
expect(mailer.send_confirmation_request(token)).to be false
end


But it doesn't work: second test failed. Why does
allow_any_instance_of
(and
allow(Mail)
) not work in this way? How that can be tested? Should am I fix my code to be more testable? I can test it by stubbing Mail#new with rspec double, but it leads to stubbing all mail methods and not looks like a right way to do.

If it does matter, I use mikel's mail gem and make tests according to his recommendations.

Answer

Mail.new doesn't return an instance of Mail, it returns an instance of Mail::Message, so you're calling allow_any_instance_of on the wrong class.

I assume the library does this to simplify the interface, but it is a little counterintuitive.