mocking an error/exception in rspec (not just its type)
I have a block of code like 开发者_如何学Cthis:
def some_method
begin
do_some_stuff
rescue WWW::Mechanize::ResponseCodeError => e
if e.response_code.to_i == 503
handle_the_situation
end
end
end
I want to test what's going on in that if e.response_code.to_i == 503
section. I can mock do_some_stuff to throw the right type of exception:
whatever.should_receive(:do_some_stuff).and_raise(WWW::Mechanize::ResponseCodeError)
but how do I mock the error object itself to return 503 when it receives "response_code"?
require 'mechanize'
class Foo
def some_method
begin
do_some_stuff
rescue WWW::Mechanize::ResponseCodeError => e
if e.response_code.to_i == 503
handle_the_situation
end
end
end
end
describe "Foo" do
it "should handle a 503 response" do
page = stub(:code=>503)
foo = Foo.new
foo.should_receive(:do_some_stuff).with(no_args)\
.and_raise(WWW::Mechanize::ResponseCodeError.new(page))
foo.should_receive(:handle_the_situation).with(no_args)
foo.some_method
end
end
Nowadays RSpec ships with verifying doubles which make sure that your mock object conforms to the real object's API (i.e. its available methods/method calls).
require 'mechanize'
class Foo
def some_method
begin
do_some_stuff
rescue WWW::Mechanize::ResponseCodeError => e
if e.response_code.to_i == 503
handle_the_situation
end
end
end
end
RSpec.describe Foo do
subject(:foo) { described_class.new }
describe "#some_method" do
subject { foo.some_method }
let(:mechanize_error) { instance_double(WWW::Mechanize::ResponseCodeError, response_code: '503') }
before { expect(foo).to receive(:do_some_stuff).and_raise(mechanize_error) }
it "handles a 503 response" do
expect(foo).to receive(:handle_the_situation) # Assert error handler will be called
subject
end
end
end
I try to write tests as clearly and cleanly as possible since code is read once by a computer, but hundreds of times by humans (your coworkers/team members)!
精彩评论