【发布时间】:2015-12-21 19:36:48
【问题描述】:
在 rspec 中使用辅助方法的常见模式如下:
# spec/spec_helper.rb
Dir[File.expand_path(File.join('..', 'support', '**', '*.rb'), __FILE__)].each { |f| require f }
###
# spec/suppport/my_helper.rb
module MyHelper
def do_something
# ...
end
end
我想像这样调用那个辅助方法:
RSpec.configure do |config|
config.include MyHelper
config.before :suite do
do_something
end
end
但是当我尝试这样做时,我收到了类似undefined local variable or method 'do_something' 的错误。我怀疑 rspec 会进行某种延迟/延迟加载,并且不会立即包含辅助模块。
如果我使用before :each 而不是before :suite,那么一切都会按预期进行。似乎该模块在 before :each 运行时已包含在内,但在 before :suite 运行时尚未包含。
在我的情况下,该块是幂等的,因此它不会像before :each 那样引起任何问题,但它的效率非常低,因为它实际上只需要在套件运行之前运行一次,而不是在每次测试之前。我确实在规范中使用了这种方法,所以我认为将它保存在辅助模块中是合适的,但是我如何在 before :suite 块中调用它?
我正在使用rspec-core 3.4.1。
【问题讨论】:
-
你不能在必要时把它放在
before(:all)块中吗?它还使测试知识保持本地化,而不是强迫寻找行为的来源。 -
@DaveNewton 使用
before :all(或before :context)确实有效(我没试过)。这使得它在功能上等同于我目前的before :suite,因为我目前只有一个顶级示例组,但这可能会改变并且会引入类似的低效率。将此块作为一次性设置/健全性检查运行一次确实有意义。感谢您的观看。 -
在测试或套件之前,我总是担心在规范助手中隐藏太多功能,因为它会导致测试中未明确显示的事情发生。对我来说,测试就是文档,这些文档包括了解这些特定测试的必要性。如果它真的广泛的功能还可以,但即便如此,我几乎总是宁愿拥有一个明确包含的帮助程序库、共享规范等。