断言在Cucumber中抛出了一个特殊的异常

JLi*_*erg 17 ruby exception-handling cucumber

脚本

我正在写一个库(没有Ruby on Rails),我想要非常详细的Cucumber功能.这尤其包括描述在各种情况下应该抛出的错误/异常.

编写Cucumber步骤最直观的方法可能就是这样

When I do something unwanted
Then an "ArgumentError" should be thrown
Run Code Online (Sandbox Code Playgroud)

问题

我必须解决两个问题:

  1. 抛出异常时,第一步不应该失败.
  2. 第一步抛出的异常应该可以进入第二步,以便做一些断言魔法.

不雅和繁琐的解决方案

我能够提出的最好的方法是在第一步中缓存异常并将其放入第二步可以访问的实例变量中,如下所示:

When /^I do something unwanted$/ do
  begin
    throw_an_exception!
  rescue => @error
  end
end

Then /^an "(.*)" should be thrown$/ do |error|
  @error.class.to_s.should == error
end
Run Code Online (Sandbox Code Playgroud)

但是,在我希望它失败的情况下,这使得第一步或多或少无用,并且它需要一个实例变量,这绝不是一件好事.

那么,任何人都可以帮助我解决至少不那么繁琐的解决方案吗?或者我应该以不同的方式编写我的功能?任何帮助将非常感激.

use*_*529 6

我再一次想到了,也许答案是:

没有优雅的解决方案,因为在您的情况下违反了Given-When-Then -Scheme.你期望"然后应该抛出异常"是"当我做一些不需要的东西"时的结果.

但是当你想到它时,这不是真的!异常不是此操作的结果,实际上异常只是显示"When"-Statement失败.

我的解决方案是在更高级别进行测试:

When I do something unwanted
Then an error should be logged
Run Code Online (Sandbox Code Playgroud)

要么

When I do something unwanted
Then the user should get an error message
Run Code Online (Sandbox Code Playgroud)

要么

When I do something unwanted
Then the program should be locked in state "error"
Run Code Online (Sandbox Code Playgroud)

或这些的组合.

然后你会在程序中"缓存异常" - 这很有道理,因为你最有可能需要这样做.

你所陈述的两个问题也将得到解决.

如果你真的必须测试异常

好吧,我猜黄瓜不是正确的测试套件,嗯?;-)

因为无论如何违反了Given-When-Then-Scheme,我只会写

When I do something unwanted it should fail with "ArgumentError"
Run Code Online (Sandbox Code Playgroud)

并且在步骤定义中有类似的东西(未经测试,如果您尝试,请纠正我)

When /^I do something unwanted it should fail with "(.*)"$/ do |errorstring|
  expect {
    throw_an_exception!
  }.to raise_error(errorstring)
end
Run Code Online (Sandbox Code Playgroud)

如上所述,由于计划被打破,这是非常错误的,但它会达到目的,不是吗?;-)

您将在rspec期望中找到有关测试错误的更多文档.