Rspec / FactoryGirl:清理数据库状态

我是Rspec和Factory girl的新手,希望我的测试能够在特定的数据库状态下运行。 我知道我可以让Factory girl创建这些记录,并且在测试运行后对象将被销毁,但是如果我在数据库中有数据会发生什么。

例如:我希望我的测试在我通过Factory Girl创建的数据库中有3条记录时运行。 但是,我目前在数据库中已有1个模型记录,我不想仅为测试删除它。 在那里有一个模型毁了我的测试。

数据库内容

[#] 

leaderboard_spec.rb

 require 'spec_helper' describe Rom::Leaderboard do describe "poll leaderboard" do it "should say 'Successful Run' when it returns" do FactoryGirl.create(:leaderboard, score: 400, name: "Alice") FactoryGirl.create(:leaderboard, score: 300, name: "Bob") FactoryGirl.create(:leaderboard, score: 200, name: "John") Leaderboard.highest_scorer.name.should == "Alice" end end end 

现在我的测试将失败,因为它会错误地认为Trudy是最高得分手,因为测试运行的状态不正确。

工厂女孩是否提供从数据库中删除记录然后回滚此删除? 类似于它在数据库中创建记录和回滚的方式

它流行使用database_cleaner gem。 你可以在这里找到它:

https://github.com/bmabey/database_cleaner

文档建议使用以下rspec配置:

 RSpec.configure do |config| config.before(:suite) do DatabaseCleaner.strategy = :transaction DatabaseCleaner.clean_with(:truncation) end config.before(:each) do DatabaseCleaner.start end config.after(:each) do DatabaseCleaner.clean end end 

这样您就可以确保每个测试都有一个干净的数据库。

尽可能直接回答您的回滚问题:没有办法在测试中回滚删除。

遵循测试约定,您的目标通常是从一个干净的平板开始,并使用factory_girl在您需要测试的数据库中有效地构建场景。

您可以通过将其添加到leaderboards.rb工厂文件来完成您想要的任务:

 factory :trudy do id 1 score 500 name "Trudy" end 

或者,您可以在测试文件中创建一个简单的辅助函数,在需要测试时重新生成该记录:

 def create_trudy FactoryGirl.create :leaderboard, id: 1, score: 500, name: "Trudy" end end 

或者您可以将所有这些放在describe块中的before(:suite)中,如下所示:

 describe "with a leaderboard record existing" do before(:each) do FactoryGirl.create :leaderboard, id: 1, score: 500, name: "Trudy" end # Tests with an initial leaderboard record end describe "with no leaderboard records initially" do # Your test above would go here end 

在最后的建议中,您的测试变得非常具有描述性,在查看输出时,您将确切知道每次测试开始时数据库的状态。