我有依赖数据库数据的测试。我一直在使用工厂在 rspec describe 块中使用 before 语句动态创建数据。
我想把它们移到跑步的起点。在继续使用工厂的同时,有没有好的方法来做到这一点?
是的,有几种方法可以解决这个问题。默认情况下,RSpec 语法
before do
end
是相同的
before :each do
end
这意味着在每个规范之前调用 before 块中的代码。
但是,您也可以使用:
before :all do
#...
end
它为定义它的描述(或其别名上下文)块运行封闭代码一次。但是,您应该小心使用before :all
,因为这意味着您的测试将不再独立运行,具体取决于您在before :all
块中定义的内容。
如果您想编写在整个套件之前运行一次的代码,您还可以在 spec_helper 文件的 RSpec 配置中定义选项 before(:suite) 和 after(:suite)。
一种更常见的方法是使用一个名为“let”的 RSpec 方法,它接受一个参数和一个块。它看起来像这样:
let(:foo) { FactoryGirl.create :user }
简而言之,该let
方法创建了一个方法别名foo
,该别名返回返回块的值(FactoryGirl.create :user
在上面的示例中)。好处是(1)它缓存了这个变量,所以块只得到一次;(2)它被延迟评估,所以它只在测试中调用 foo 时运行并缓存块中的值。重要的是要记住,有时这种惰性求值会在某些情况下导致意外行为。您可以改用它let!
来防止延迟加载。该let
方法在任何语句之前运行,因此您before
可以使用块中定义的任何方法。let
before
最后,还有一个名为 FactoryGirl Seeds 的项目,它允许您在 spec_helper 中定义只运行一次的生成器。个人没有使用太多,所以我不确定它有多可靠,但您可以在此处找到更多信息: