我试图习惯用简单的驱动程序片段测试我的代码,并想测试是否抛出Argument Error而不退出程序。这是我正在使用的代码
class Die
def initialize(sides)
@sides=sides
unless @sides>0
raise ArgumentError.new("Your number sucks, yo")
end
end
#returns the number of sides of a die
def sides
@sides
end
#generates a random die roll based on the number of sides
def roll
rand(@sides)+1
end
end
这就是我试图打电话来进行测试的。
p bad=Die.new(0)=="Your number sucks, yo"
我希望它返回的是" true"。它在终端中返回的是:
w3p1_refact.rb:33:in `initialize': Your number sucks, yo (ArgumentError)
from w3p1_refact.rb:69:in `new'
from w3p1_refact.rb:69:in `<main>'
我可以重写这个以返回我要找的东西吗?
答案 0 :(得分:5)
当引发异常但尚未处理时(
rescue
,ensure
,at_exit
和END
阻止) 全局变量$ !将包含当前异常 ,$ @包含当前异常的回溯。
因此,一旦我在$!
全局变量中引发异常,我就可以使用Exception#message
方法,返回异常的消息或名称。
您使用Kernel#raise
没有参数,在$中引发异常!或者如果$,则引发RuntimeError!没有。 使用单个String参数,将字符串作为消息引发RuntimeError。否则,第一个参数应该是Exception类的名称(或者在发送异常消息时返回Exception对象的对象) 。可选的第二个参数设置与异常关联的消息,第三个参数是回调信息的数组。 例外情况由开始...结束块的救援条款捕获。
我会这样做:
class Die
def initialize(sides)
@sides=sides
unless @sides>0
raise ArgumentError.new("Your number sucks, yo")
# As per the doc you could write the above line as below also
# raise ArgumentError, "Your number sucks, yo"
end
end
#returns the number of sides of a die
def sides
@sides
end
#generates a random die roll based on the number of sides
def roll
rand(@sides)+1
end
end
Die.new(0) rescue $!.message == "Your number sucks, yo"
# => true
以上内联救援代码也可以写成:
begin
Die.new(0)
rescue ArgumentError => e
bad = e.message
end
bad == "Your number sucks, yo" # => true