有没有办法在方法中测试Argument Errors以返回true或false?

not*_*off 2 ruby testing argument-error

我试图习惯用简单的驱动程序片段测试我的代码,并想测试是否抛出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
Run Code Online (Sandbox Code Playgroud)

以下是我试图要求进行测试的内容.

p bad=Die.new(0)=="Your number sucks, yo"
Run Code Online (Sandbox Code Playgroud)

我希望它返回的是"真实的".它在终端中返回的是:

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>'
Run Code Online (Sandbox Code Playgroud)

我可以重写这个以返回我要找的东西吗?

Aru*_*hit 5

Exception的文档

当一个异常被提出,但尚未处理(在rescue,ensure,at_exitEND块)的全局变量$!将包含当前异常,$ @包含当前异常的回溯.

所以一旦我刚刚在$!全局变量中引发了异常,我就可以使用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
Run Code Online (Sandbox Code Playgroud)

上面的内联救援代码也可以写成:

begin
  Die.new(0)
rescue ArgumentError => e
  bad = e.message
end 
bad == "Your number sucks, yo" # => true
Run Code Online (Sandbox Code Playgroud)

  • 是的,我知道它有效,但我认为它作为一种解释并没有那么有用.很明显,提问者并没有正确地了解"救援",如果你要提供一个答案,那么它应该是一个有用的答案.我的观点当然. (2认同)