Каков правильный способ проверки обработки ошибок?

В последнее время я много работал с драгоценным камнем Mechanize и хотел бы включить несколько тестов, чтобы убедиться, что я выявляю правильные ошибки. Каков правильный способ проверки обработки ошибок?

Это мой основной метод:

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

Я иду в правильном направлении? Приветствуются любые идеи и/или ресурсы.


person binarymason    schedule 14.10.2015    source источник


Ответы (3)


Вроде, как бы, что-то вроде. Вы не должны тестировать зависимые библиотеки повторно в своем приложении. Достаточно поймать Net::HTTP::Persistent::Error, не проверяя, работает ли базовая функциональность. Хорошо написанные гемы должны предоставлять свои собственные тесты, и вы должны иметь доступ к этим тестам по мере необходимости, тестируя этот гем (например, 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)
person jjk    schedule 14.10.2015
comment
@jjk спасибо за ваш ответ. Некоторым фоном для этого является то, что мой поисковый робот получал все типы ошибок в прошлом, будь то попытка доступа к несуществующей странице или просто тайм-аут соединения. Mechanize выдает каждую из ошибок соответствующим образом, я хочу проверить обработку. - person binarymason; 14.10.2015
comment
поэтому, если вам нужно быть явным, вы должны создать фиктивный объект, полагаясь на каждый из этих базовых объектов. Тогда вы можете иметь дело с ними, чтобы подняться, или что-то еще. Вы заметили, что я использую экземпляр double rspec для создания интерфейса, который я могу использовать. Затем я могу сослаться на это в экземпляре моего фиктивного объекта. Если это полезно, отметьте этот ответ как правильный. - person jjk; 14.10.2015
comment
Спасибо, что направил меня в правильном направлении, @jjk. Маркировка решена. - person binarymason; 15.10.2015

Это ссылка на то, где я нашел ответ, более соответствующий тому, что я спрашиваю: https://stackoverflow.com/a/17825110/5381605

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
person binarymason    schedule 15.10.2015
comment
рад, что вы нашли свое решение - person akostadinov; 15.10.2015

вам нужно mock Mechanize класс. искать другие вопросы как сделать

person akostadinov    schedule 14.10.2015