Тестирование Rspec и спасение метода

Есть ли способ проверить rspec, если ошибка возникла и была спасена? Если у меня есть спасение, мой тест rspec не видит возникшую ошибку, а только приводит к спасению?

module MyApp
  def some_method(msg)
     raise StandardError.new(msg)
  end

  def second_method(msg)
    begin
      count = 0
      some_method(msg)
    rescue StandardError=> e
      puts e
      count = 1
    end
  end
end

RSpec.describe Myapp do
  describe "#some_method" do
    it "should raise error" do
       expect {
        some_method("this is an error")
      }.to raise_error(StandardError) {|e|
        expect(e.message).to eql "this is an error"
      }
    end
  end

  # this fails, as the error is not raised
  describe "#second_method" do
    it should raise error and rescue do
      expect {
        a = second_method("this is an error and rescue")
      }.to raise_error(StandardError) {|e|
        expect(e.message).to eql "this is an error and rescue"
        expect(a) = 1
      }
    end
  end
end

person user2012677    schedule 08.09.2020    source источник
comment
Возможно, это проблема X/Y. По определению, если вы спасли исключение, оно больше не вызывается, пока вы не вызовете его повторно. Если вы хотите отслеживать ранее обработанные исключения, вам нужно будет управлять своим собственным объектом хранения, чтобы он сохранялся за пределами предложений восстановления/обеспечения для отслеживания $! и $@.   -  person Todd A. Jacobs    schedule 08.09.2020
comment
Что значит $! и $@значит?   -  person user2012677    schedule 08.09.2020
comment
Ruby отсылает к Ларри Уоллу, поддерживая ряд загадочных системных глобальных переменных, две из которых — $! и $@. Если вы require 'English' в верхней части файла, вы можете называть их более информативными именами $ERROR_INFO и $ERROR_POS   -  person nullTerminator    schedule 08.09.2020


Ответы (1)


Как правило, вы не хотите вызывать или спасать StandardError напрямую, потому что это довольно неинформативно и не будет обнаруживать ошибки за пределами Иерархия StandardError. Вместо этого вы обычно хотите проверить, было ли возбуждено конкретное исключение, или что был вызван определенный класс ошибки или сообщение об ошибке.

Если вы знаете обычай или встроенный класс исключений, который вам нужен, или конкретное сообщение об ошибке, а затем проверьте его явным образом. Например:

it 'should raise an ArgumentError exception' do
  expect { MyApp.new.foo }.to raise_error(ArgumentError)
end

it 'should raise MyCustomError' do
  expect { MyApp.new.foo }.to raise_error(MyCustomError)
end

it 'should raise StandardError with a custom message' do
  msg = 'this is a custom error and rescue'
  expect { MyApp.new.foo }.to raise_error(msg)
end

Если вы не знаете (или не заботитесь) о конкретном исключении или сообщении, которое должно быть вызвано, но ожидаете, что какое-то исключение прервет поток выполнения, вам следует использовать голый raise_error. Например:

it "should raise an exception" do
  expect { MyApp.new.foo }.to raise_error
end
person Todd A. Jacobs    schedule 08.09.2020
comment
спасибо за ваш пост, но если я не правильно понимаю, я не верю, что он касается моего вопроса. (В качестве примера я использовал стандартную ошибку, обычно это конкретная ошибка.) - person user2012677; 08.09.2020