RSpec在测试数据库中留下记录

时间:2013-10-06 14:21:42

标签: ruby-on-rails ruby rspec

每当我运行用户测试时,RSpec会在测试完成后将Fabricated用户留在测试数据库中,这会弄乱我的其他测试。我将执行rake db:test:prepare,但是当我再次运行测试时,会在我的数据库中重新创建记录。我不知道为什么会这样。它只发生在用户对象上。

在我的spec_helper文件中,我甚至有:

config.use_transactional_fixtures = true

以下是创建记录的示例测试:

it "creates a password reset token for the user" do
  alice = Fabricate(:user) 
  post :create, email: alice.email
  expect(assigns(alice.password_reset_token)).to_not eq(nil)
end

制造商:

Fabricator(:user) do
  email { Faker::Internet.email }
  password 'password'
  name { Faker::Name.name }
end

这可能与我的用户模型有关吗?

4 个答案:

答案 0 :(得分:20)

你应该使用一个名为database_cleaner的gem来截断你的数据库并自动重置所有内容,所以在你的gem文件中添加gem database_cleaner之后你的spec_helper.rb配置它

spec_helper.rb

config.use_transactional_fixtures = false

config.before(:suite) do
  DatabaseCleaner.strategy = :truncation
end

config.before(:each) do
  DatabaseCleaner.start
end

config.after(:each) do
  DatabaseCleaner.clean
end

然后在spec / support目录中创建一个新文件

规格/支持/ shared_db_connection.rb

class ActiveRecord::Base
  mattr_accessor :shared_connection
  @@shared_connection = nil

  def self.connection
    @@shared_connection || retrieve_connection
  end
end
ActiveRecord::Base.shared_connection=ActiveRecord::Base.connection

现在,无论何时运行测试,数据库都将被重置。这来自Aaron Sumner撰写的“使用RSpec进行日常Rails测试”一书

答案 1 :(得分:5)

每个测试都包含在数据库事务中。这意味着测试期间创建的所有内容都应该在测试结束时消失。因此,我怀疑数据库中的任何内容都是在测试之外进行的(例如在before(:all)块中)。

此外,这并不能保证每次运行测试时数据库都是空的。有可能你不小心意外添加了一条记录,现在它只是不断恢复到那个状态。

如果你想确保你的测试每次都有一个闪亮的数据库,你应该看一下database_cleaner gem。

答案 2 :(得分:1)

最简单的解决方案是确保RSpec测试在事务中运行(Rails默认执行此操作)

spec_helper.rb

config.around(:each) do |example|
  ActiveRecord::Base.transaction do
    example.run
    raise ActiveRecord::Rollback
  end
end

答案 3 :(得分:0)

如果我不得不猜测,行post :create, email: alice.email似乎可能是进行实际用户创建的候选者。

使用虚假测试将该行删除,并查看您是否仍在获取在数据库中创建的用户。