2017-02-22 107 views
1

Есть ли способ узнать, было ли возбуждено или исключено какое-либо исключение во время выполнения какого-либо кода?Как проверить, было ли спасено какое-либо исключение?

Предпочтительно в тестах написано с ActiveSupport::TestCase и не RSpec

Есть ли глобальный рубин стека исключений или что-то, что я мог проверить?

+1

Настройте приспособление так, что это повысит ошибка и убедитесь, что ошибка не протекала. – ndn

+0

@ndn Как я могу поднять ошибку изнутри прибора? Btw, ошибка не в данных, а в самом коде .. – Magne

+0

Посредством я не имел в виду крепления рельса, я имел в виду предварительные условия/среду, в которой вы запускаете свои тесты. Просто убедитесь, что все необходимое для повышения ошибки выполняется в настройке. – ndn

ответ

1

Как пояснили в комментариях, ОП нуждался в нем для отладки, а не для записи тестов.


Kernel#set_trace_func позволяет перехватывать низкие события уровня, такие как воспитываются ошибка:

set_trace_func(proc do |event, *_| 
    puts 'Raised!' if event == 'raise' 
end) 

raise 'Oh, no!' rescue :foo 

Вы можете запустить #set_trace_func перед кодом вы пытаетесь отлаживать. Если исключение не было поднято, но рейк был зарегистрирован крюком - кто-то его спас.


Это может создать некоторый шум в зависимости от того, что вы выполняете. К счастью, вы можете фильтровать вниз файл и строку:

set_trace_func(proc do |event, file, line, *_| 
    if event == 'raise' && file == 'test.rb' && line == 42 
    puts "Raised on #{file}:#{line}!" 
    end 
end) 

Он даже дает переплета, так что вы можете упасть вниз отладчик:

require 'irb' 

set_trace_func(proc do |event, *_, error_binding, _| 
    error_binding.irb if event == 'raise' 
end) 

def foo 
    bar = 42 
    raise 'Oh, no!' rescue :baz 
end 

foo 

# Opens an irb 
# > bar # => 42 
+0

Спасибо! Это было великолепно! – Magne

6

Если вы хотите быть монстром, вы можете инструмент сами ошибки:

class StandardError 
    @@called = false 

    def initialize 
    @@called = true 
    super 
    end 

    def self.called 
    @@called 
    end 
end 

#test it out like so: 

def raise_arg_error 
    raise ArgumentError 
rescue 
end 

puts ArgumentError.called #false 
raise_arg_error 
puts ArgumentError.called #true 

Отлично подходит для специальных проверок здравомыслие. Ужасно для производственного кода.

+2

Это ужасно! Но мне это нравится ... – Jakir00

+0

Интересный подход! Возможно, я мог бы сделать это только в тестовом коде .. (не уверен, что это было бы разумно в соответствии с лучшими практиками тестовой методологии, хотя ..). Почему это ужасно для производственного кода? Дополнительный атрибут не влияет на то, как работает NormalError, поэтому он не обязательно нарушит ожидания программиста. – Magne

+0

@Magne Это приятный маленький wtf для нового разработчика, который придет на ваш проект и узнает. И тогда он собирается использовать его для реализации фактической производственной функции. – fylooi