2014-01-25 34 views
1

我想要习惯用简单的驱动程序片段来测试我的代码,并且想要测试一个参数错误是否在不脱离程序的情况下抛出。这里是我使用的代码有没有办法从一个方法内测试参数错误来返回true或false?

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>' 

我可以重写这个以返回我在找什么吗?

回答

4

Exception

当一个异常被提出,但尚未处理的文档(rescueensureat_exitEND块)全局变量$!将包含当前异常,并且$ @包含当前异常的回溯。

所以一旦我刚才提出的$!全局变量例外,我可以用Exception#message方法,它返回异常的消息或名称。

您使用Kernel#raise

不带任何参数,引发异常的$!或者如果$!引发RuntimeError是零。 使用单个String参数引发RuntimeError,并将该字符串作为消息。否则,第一个参数应该是Exception类的名称(或发送异常消息时返回Exception对象的对象)。可选的第二个参数设置与异常关联的消息,第三个参数是一个回调信息数组。 异常由begin ... end块的救援条款捕获。

我会做如下:

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 
+1

我认为这将有助于拼出用'开始...救援ArgumentError => e ... end'块来拯救,这样它就完全清楚你在做什么,并且还要注意你在这里的缩短形式不太明显。 – jeremycole

+1

@jeremycole我认为它会工作,根据代码。因为该消息将被设置,只有当异常来自该部分。否则,它总会是'假'。 –

+2

是的,我知道它的工作原理,但我认为它作为解释的帮助很少。很明显,提问者不知道“救援”是否正确,如果你要提供一个答案和例子,它应该是一个有用的答案。我的意见当然。 – jeremycole

相关问题