使用assert_raises的重构测试

时间:2014-04-28 19:19:49

标签: ruby unit-testing minitest

我有一个测试块:

describe 'without' do

  describe 'author' do
    let(:author)  {nil}
    it('fails')   {assert_raises(ArgumentError) { excerpt }}
  end

  describe 'title' do
    # same content as above, but testing title
  end

  describe 'content' do
    # same content as above, but testing content
  end

end

这很好,测试通过 - 但由于这里有很多重复,我想重构:

describe 'without' do

  describe 'author' do
    let(:author)  {nil}
    it('fails')   {assert_failure(excerpt} # added a method in this line
  end

  describe 'title' do
    # same content as above, but testing title
  end

  describe 'content' do
    # same content as above, but testing content
  end

  # and the method here
  def assert_failure(instance)
    assert_raises(ArgumentError) { instance }
  end

end

但是这不起作用 - 我的测试失败并出现以下错误:

construction::without::author#test_0001_fails:
ArgumentError: Excerpt cannot be built: Author missing

我希望在缺少信息的情况下提出错误 - 这正是我正在测试的错误。因此,似乎在提取此断言时,ArgumentError被提升并在assert_raises进行任何比较之前停止测试。我查看了code这个断言,但是我无法弄清楚为什么当代码被提取到另一个方法时会发生这种情况,而不是当它在线时。

1 个答案:

答案 0 :(得分:1)

使用以下语法编写时:

assert_raises(ArgumentError) { excerpt }

您实际传递给assert_raises的是block。这意味着在方法本身决定要对其进行评估之前,不会对代码(excerpt)进行求值。

但是使用这种语法:

assert_failure(excerpt)
excerpt开始之前,

assert_failure会被评估

如果要复制上述行为,则需要传递assert_failure块:

def assert_failure(&block)
  assert_raises(ArgumentError, &block)
end

  describe 'author' do
    let(:author)  {nil}
    it('fails')   { assert_failure { excerpt } }
  end