它在这里说https://www.relishapp.com/rspec/rspec-core/v/3-5/docs/helper-methods/let-and-let let定义的变量在不同的例子中有所变化。 我做了与文档相同的简单测试,但使用了AR模型:
RSpec.describe Contact, type: :model do
let(:contact) { FactoryGirl.create(:contact) }
it "cached in the same example" do
a = contact
b = contact
expect(a).to eq(b)
expect(Contact.count).to eq(1)
end
it "not cached across examples" do
a = contact
expect(Contact.count).to eq(2)
end
end
第一个例子通过,但第二个失败了(预期2,得到1)。所以contacts
表在第二个例子之前再次为空,尽管有文档。
我正在使用let
,并确保它在每个it
块中具有相同的值,我的测试证明了这一点。所以假设我误解了文档。请解释一下。
P.S。我用DatabaseCleaner
P.P.S我把它关掉了。什么都没有改变。
修改
我关闭了DatabaseCleaner和transational fixture并测试通过。
据我所知(编程新手),let
每个it
块都会被评估一次。如果我有三个示例,每个示例都调用contact
变量,我的测试数据库最后将增长到三个记录(我已经测试过,所以它确实如此)。
对于正确的测试行为,我应该使用DatabaseCleaner。
答案 0 :(得分:1)
您展示的行为是正确的行为。在设置正确的环境时,没有任何示例依赖于另一个示例!如果您确实依赖于缓存,那么您只是在以后遇到麻烦。
该文档中的示例只是试图证明关于使用全局变量进行缓存的一个观点 - 对于单独测试Rails应用程序来说,这是一个完全不同的场景 - 依靠先前的示例来设置一些东西并不是一种好的做法。
让我们假设你接着编写了10个其他的测试,所有这些都依赖于前面的例子创建了对象的事实。然后在将来的某个时候你会删除其中一个例子......砰!之后的每次测试都会突然失败。
每个测试都应该能够独立于任何其他测试进行测试!
答案 1 :(得分:1)
P.S。我使用DatabaseCleaner
这就是第二个示例中数据库为空的原因。与let
无关。