NoMethodError:未定义的方法`RuntimeError'当我使用{...}语法代替do ...以minitest结束时

时间:2016-11-28 17:04:16

标签: ruby minitest

我使用minitest来测试一个带有引发异常的方法的类。我使用another question中描述的技术,但我有一些令人困惑的结果:

代码:

class Formatter
  def output_report
    raise "Abstract method called: #{__method__}"
  end
end

试验:

require 'minitest/autorun'
require_relative 'formatter'

class TestFormatter < Minitest::Test
  def setup
    @formatter = Formatter.new
  end

  def test_formatter_error_when_abstract_method_called
    err = assert_raises RuntimeError { @formatter.output_report }
    assert_equal "Abstract method called: output_report", err.message
  end
end

我预计测试通过,除了我得到以下错误:

Run options: --seed 64742

# Running:

E

Finished in 0.001274s, 784.9294 runs/s, 0.0000 assertions/s.

  1) Error:
TestFormatter#test_formatter_error_when_abstract_method_called:
NoMethodError: undefined method `RuntimeError' for #<TestFormatter:0x007fd07a2b93d0>
    test_formatter.rb:10:in `test_formatter_error_when_abstract_method_called'

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

但是如果我使用do...end块语法而不是{...},则测试通过

操作结束:

require 'minitest/autorun'
require_relative 'formatter'

class TestFormatter < Minitest::Test
  def setup
    @formatter = Formatter.new
  end

  def test_formatter_error_when_abstract_method_called
    # err = assert_raises RuntimeError { @formatter.output_report }
    err = assert_raises RuntimeError do
      @formatter.output_report
    end
    assert_equal "Abstract method called: output_report", err.message
  end
end

输出:

Run options: --seed 37315

# Running:

.

Finished in 0.001298s, 770.4160 runs/s, 1540.8321 assertions/s.

1 runs, 2 assertions, 0 failures, 0 errors, 0 skips

为什么会这样?我认为do...end等于{...},除了在制作多行广告时使用前者的约定?

1 个答案:

答案 0 :(得分:2)

do..end{...}之间存在显着差异:优先级很重要。卷曲是贪婪的,do...end不是。

受挫的例子:

puts [1].each { |i| i }    #⇒ 1
puts [1].each do |i| i end #⇒ #<Enumerator:0x000000067dd678>

那就是说,为了使curlies按预期工作,应该使用括号:

assert_raises(RuntimeError) { @formatter.output_report }