我有一个测试做了这件事:
expect(@parser.parse('adsadasdas')).to raise_error(Errno::ENOENT)
但它没有起作用。我改成了:
expect { @parser.parse('adsadasdas') }.to raise_error(Errno::ENOENT)
它有效了。
我们在 expect 中何时使用花括号,何时使用圆括号?
@parser.parse('adsadasdas')
作为参数(使用括号)传递给expect
时,您实际上是在告诉 Ruby:@parser.parse('adsadasdas')
。
2.取得结果并将其传递给expect
。
3.expect
应查看此结果是否符合我的预期(也就是说,是否会引发Errno:ENOENT
)。@parser.parse('adsadasdas')
时,错误会立即引发。Ruby甚至没有机会将结果传递给expect
。(就我们所知,您可以将@parser.parse('adsadasdas')
作为参数传递给任何函数……比如multiply()
或capitalize()
)错误已经被引发了,expect
甚至没有机会完成它的工作。@parser.parse('adsadasdas')
作为代码块(一个 Proc)传递给expect
时,您要告诉 Ruby 的是:expect
,准备开始工作。
2.expect
,我希望你在评估@parser.parse('adsadasdas')
时跟踪发生的情况。
3.好的,expect
,刚刚执行的代码块是否引发Errno:ENOENT
错误?我希望它会这样做。expect
时,您要告诉expect
,您希望它检查代码块执行后产生的行为变化,并让您知道它是否符合您提供的预期。expect
传递参数时,您正在告诉 ruby 在expect
参与之前评估该参数以得出某个值,然后将该值传递给expect
以查看是否符合某些期望。expect(exp)
来指定关于 exp
的 值 的某些内容,使用 expect { exp }
来指定在执行 exp
时发生的 副作用。
raise_error
请注意,一个方法可以返回异常,这与引发异常不同。抛出异常是一种副作用,只有通过使用适当的rescue
子句执行块,匹配器才能观察到它。因此,此匹配器必须接收一个块才能正常工作。
throw_symbol
抛出符号类似于引发错误——它会导致堆栈跳转,并且是一种只能通过在适当的catch
块中运行块来观察的副作用。
change
expect { |probe| [1, 2, 3].each(&probe) }.to yield_with_successive_args(1, 2, 3)
所有这些匹配器有什么共同点?它们都不能用于简单的 Ruby 值。相反,它们都必须在适当的上下文中包装一个块(即在值之前/之后捕获或检查)。
请注意,在 RSpec 3 中,我们 添加了一些逻辑,以便在用户使用给定匹配器的错误 expect
形式时为其提供清晰的错误信息。然而,在特定情况下,即 expect(do_something).to raise_error
,我们无法为您提供明确的解释 - 如果 do_something
引发错误(正如您所期望的那样...),则错误会在 Ruby 评估 to
参数(即 raise_error
匹配器)之前引发,因此 RSpec 无法检查匹配器是否支持值或块期望。
简而言之:
行为
时返回值
时值得一读:至于规则,如果要测试行为(例如引发错误、更改某个值),则传递一个块或Proc。否则,传递一个“常规”参数,在这种情况下,该参数的值是被测试的。
- 来自这个回答
expect
方法之前就被执行了,但使用块时,expect
将自己运行代码。expect { @parser.parse(url) }.to include(known_url)
不起作用,但如果我使用括号,它就可以工作。为什么? - Hommer Smith