我有一个大型模型需要时间来初始化我的RSpec测试。
我希望每个示例都可以使用它,但是如果示例需要它,则只想加载它。
这似乎是let()
延迟加载的完美用法 - 只在您需要时加载它。
在任何特定的spec文件中我都可以
require "spec_helper"
feature "foo" do
let(:big_class) { MyBigClass.new(bar) }
...
end
这将使big_class
可用于该spec文件中的每个示例。
有没有办法让它更全局化,以便每个spec文件和示例都可以使用它?我找不到在规范助手中初始化let
的好方法。
答案 0 :(得分:2)
您可以简单地定义shared context并将其包含在每个示例中。关于您的具体问题,它应如下所示:
RSpec.shared_context "Global helpers" do
let(:big_class) { MyBigClass.new(bar) }
end
RSpec.configure do |config|
config.include_context "Global helpers"
end
但是,在所有示例中包含共享上下文并不是一个好主意,并且来自您的问题的big_class
帮助器看起来确实是特定于域的。您可以通过元数据引导共享上下文包含,例如,当您只想在要素规范中包含给定的共享上下文时(默认情况下它们都设置了:type => :feature
元数据),您可以这样做:
RSpec.configure do |config|
config.include_context "Feature spec helpers", :type => :feature
end
答案 1 :(得分:1)
您可以考虑其他方法:
模拟对象当然会带来一系列弊端;它们会变得陈旧,使测试变得更脆弱。但对于一些不是问题的测试。
重构初始化程序是我的最爱。 E.g。
MyBigObject.new(args)
变为
MyBigObject.new(args).setup
或:load_data
或:connect_to_database_on_the_moon
或其他需要很长时间的事情。你得到了照片。
显然这意味着更改您的代码,但我发现通常可以通过其他方式提供帮助,这肯定会使测试更容易。
答案 2 :(得分:0)
您不想使用let
。来自文档:
使用let来定义memoized帮助器方法。该值将缓存 同一个示例中的多个调用但不跨越示例。
您最终会多次实例化MyBigClass。我建议在spec_helper.rb(或类似)中的某处创建一个全局帮助器方法,如果已经设置了缓存值,则使用memo-ization自己返回缓存值。
同样要非常小心这一切,因为你违反了孤立测试的规则。对你正在做的事情可能没什么问题,但这只是一面红旗。
答案 3 :(得分:0)