【问题标题】:Is there a way to test Argument Errors from within a method to return true or false?有没有办法从方法中测试参数错误以返回真或假?
【发布时间】:2014-01-25 17:42:29
【问题描述】:

我正在尝试习惯于使用简单的驱动程序 sn-ps 测试我的代码,并想测试是否在不退出程序的情况下引发了参数错误。这是我正在使用的代码

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"

我希望它返回的是“真”。它在终端中返回的是:

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

我可以重写它以返回我正在寻找的东西吗?

【问题讨论】:

    标签: ruby testing argument-error


    【解决方案1】:

    来自Exception的文档

    当异常已引发但尚未处理时(在rescueensureat_exitEND 块中)全局变量 $!将包含当前异常,而 $@ 包含当前异常的回溯。

    因此,一旦我刚刚在 $! 全局变量中引发了异常,我就可以使用 Exception#message 方法,该方法返回异常的消息或名称。

    你使用Kernel#raise

    不带参数,在 $! 中引发异常或引发 RuntimeError 如果 $!是零。 使用单个字符串参数,引发一个带有字符串作为消息的 RuntimeError。否则,第一个参数应该是异常类的名称(或发送异常消息时返回异常对象的对象)。可选的第二个参数设置与异常关联的消息,第三个参数是回调信息数组。 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
    

    【讨论】:

    • 我认为用 begin ... rescue ArgumentError =&gt; e ... end 块拼出救援会很有帮助,这样你就可以完全清楚你在做什么,还要注意你在这里的缩短形式,这不太明显.
    • @jeremycole 根据代码,我认为它会起作用。因为只有当异常来自该部分时才会设置消息。否则它将始终为false
    • 是的,我知道它有效,但我认为它作为解释的帮助要小得多。显然,提问者对rescue 并不了解,如果您要提供答案和示例,它应该是有帮助的。当然是我的意见。
    • @jeremycole 完成!请检查。
    猜你喜欢
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    相关资源
    最近更新 更多