RSpec,隐式主题和异常

时间:2011-07-26 23:05:14

标签: ruby rspec

有没有办法在rspec中使用隐式主题正确测试异常提升?

例如,这失败了:

describe 'test' do
  subject {raise 'an exception'}
  it {should raise_exception}
end

但这传递了:

describe 'test' do
  it "should raise an exception" do
    lambda{raise 'an exception'}.should raise_exception
  end
end

为什么会这样?

2 个答案:

答案 0 :(得分:7)

subject接受返回剩余主题的块。

你想要的是这个:

describe 'test' do
  subject { lambda { raise 'an exception' } }
  it { should raise_exception }
end

编辑:评论澄清

此:

describe 'test' do
   subject { foo }
   it { should blah_blah_blah }
end

或多或少等同于

(foo).should blah_blah_blah

现在,请考虑:如果没有lambda,则会变为:

(raise 'an exception').should raise_exception

在此处看到,在评估主题时(在完全调用should之前)会引发异常。而对于lambda,它变成:

lambda { raise 'an exception' }.should raise_exception

这里,主题是lambda,仅在评估should调用时(在将捕获异常的上下文中)进行评估。

虽然每次都会重新评估“主题”,但仍需要评估您要调用should的内容。

答案 1 :(得分:1)

另一个答案很好地解释了解决方案。我只想提一下RSpec有一个名为expect的特殊助手。它只是更容易阅读:

# instead of saying:
lambda { raise 'exception' }.should raise_exception

# you can say:
expect { raise 'exception' }.to raise_error

# a few more examples:
expect { ... }.to raise_error
expect { ... }.to raise_error(ErrorClass)
expect { ... }.to raise_error("message")
expect { ... }.to raise_error(ErrorClass, "message")

更多信息可在RSpec documentation on the built-in matchers

中找到