测试错误处理的正确方法是什么?

What is proper way to test error handling?

我最近一直在使用 Mechanize gem,我想加入一些测试以确保我能捕捉到正确的错误。测试错误处理的正确方法是什么?

这是我的基本方法:

def get(str)
  url = format_url(str)
  #puts "sending GET request to: #{url}"
  sleep(0.1)
  @page = Mechanize.new do |a|
    a.user_agent_alias = 'Mac Safari'
    a.open_timeout = 7
    a.read_timeout = 7
    a.idle_timeout = 7
    a.redirect_ok = true
  end.get(url)

rescue Mechanize::ResponseCodeError => e
  puts "#{'Response Error:'.red} #{e}"
rescue SocketError => e
  puts "#{'Socket Error:'.red} #{e}"
rescue Net::OpenTimeout => e
  puts "#{'Connection Timeout:'.red} #{e}"
rescue Errno::ETIMEDOUT => e
  puts "#{'Connection Timeout:'.red} #{e}"
rescue Net::HTTP::Persistent::Error
  puts "#{'Connection Timeout:'.red} read timeout, too many resets."
end

这是处理错误测试的开始:

class TestErrorHandling < Mechanize::TestCase
  context 'Example when sending a GET request' do
    should 'rescue error and return nil' do
      assert_equal nil, Example.get('http://localhost/pagethatdoesntexist')
    end
  end
end

我的方向是否正确?欢迎任何见解 and/or 资源。

您需要 mock Mechanize class。搜索其他问题怎么做

有点。您不应该在您的应用程序中再次测试依赖库。在不确保底层功能正常工作的情况下捕获 Net::HTTP::Persistent::Error 就足够了。写得好的 gems 应该提供他们自己的测试,并且您应该能够根据需要通过测试 gem(例如 Mechanize)来访问这些测试。

您可以模拟这些错误,但您应该谨慎行事。这是一些模拟 SMTP 连接的代码

 class Mock
    require 'net/smtp'

    def initialize( options )
      @options = options
      @username = options[:username]
      @password = options[:password]
      options[:port] ? @port = options[:port] : @port = 25
      @helo_domain = options[:helo_domain]
      @from_addr = options[:from_address]
      @from_domain = options[:from_domain]

      #Mock object for SMTP connections
      mock_config = {}
      mock_config[:address] = options[:server]
      mock_config[:port] = @port

      @connection = RSpec::instance_double(Net::SMTP, mock_config)

      allow(@connection).to receive(:start).and_yield(@connection)
      allow(@connection).to receive(:send_message).and_return(true)
      allow(@connection).to receive(:started?).and_return(true)
      allow(@connection).to receive(:finish).and_return(true)
    end
    #more stuff here
 end

我没有看到您测试任何在这里更有意义的自定义错误。例如,您可以测试参数中的 url-不友好字符并从中拯救。在那种情况下,您的测试将提供一些明确的内容。

 expect(get("???.net")).to raise_error(CustomError)

这是 link 我找到的答案更符合我的要求:

describe 'testing' do
  it 'must raise' do
   a = Proc.new {oo.non_existant}
   begin
     a[]
   rescue => e
    end
   e.must_be_kind_of Exception
  end
end