在rspec中模拟错误/异常(不只是它的类型)

时间:2010-01-14 21:44:19

标签: ruby-on-rails ruby rspec

我有一个像这样的代码块:

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

我想测试if e.response_code.to_i == 503部分中发生了什么。我可以模拟do_some_stuff来抛出正确的异常类型:

whatever.should_receive(:do_some_stuff).and_raise(WWW::Mechanize::ResponseCodeError)

但是当我收到“response_code”时,如何模拟错误对象本身返回503?

2 个答案:

答案 0 :(得分:22)

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

答案 1 :(得分:0)

现在,RSpec随verifying doubles一起提供,可确保您的模拟对象符合真实对象的API(即其可用方法/方法调用)。

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

由于计算机只能读取一次代码,而人类(您的同事/团队成员)却可以读取数百次代码,因此我尝试尽可能清晰,简洁地编写测试!