开发者

mocking an error/exception in rspec (not just its type)

开发者 https://www.devze.com 2022-12-16 23:03 出处:网络
I have a block of code like 开发者_如何学Cthis: def some_method begin do_some_stuff rescue WWW::Mechanize::ResponseCodeError => e

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)!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号