在 Rails 3 上使用 Rspec 和 MongoID 清理或重置测试数据库

Posted

技术标签:

【中文标题】在 Rails 3 上使用 Rspec 和 MongoID 清理或重置测试数据库【英文标题】:Clean out, or reset test-database with Rspec and MongoID on Rails 3 【发布时间】:2011-09-28 20:14:20 【问题描述】:

当我运行我的 rspec 测试时,由于我的 mongodb 数据库中的数据过时,许多测试都失败了。 AFAIK 使用干净的数据库进行测试要好得多。

使用 mysql,我可以运行 rake db:test:prepare 来清理数据库。如何在每次测试之前清理和/或重新植入数据库?

【问题讨论】:

【参考方案1】:

如果您使用多个 MongoDB 客户端,或者您不使用默认客户端,例如,您可以在 mongoid.yml 中创建一个新客户端,例如:'actions'。

您需要指定连接名称。 例如对于“动作”客户端使用:

config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

config.before(:each) do
  DatabaseCleaner[:mongoid,  connection: :actions ].start
  DatabaseCleaner.start
end

config.after(:each) do
  DatabaseCleaner[:mongoid,  connection: :actions ].clean
  DatabaseCleaner.clean
end

【讨论】:

【参考方案2】:

添加到 gemfile:

gem 'database_cleaner', :github => 'bmabey/database_cleaner'

运行bundle install

将此添加到您的 spec_helper:

config.before(:suite) do
  DatabaseCleaner[:mongoid].strategy = :truncation
  DatabaseCleaner[:mongoid].clean_with(:truncation)
end

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

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

全部功劳归于: http://blog.codelette.com/2013/07/07/make-rspec-clean-up-mongoid-records/

【讨论】:

为什么你刚刚删除了关于类变量的问题?这是一个很好的,我有一个答案给你。【参考方案3】:

在 Mongoid v2.0.2 中

before(:each) do
    Mongoid.purge!
end

Rdoc: Mongoid.purge!

【讨论】:

当我尝试选择的答案时没有工作,仍然有一些记录以某种方式创建,这对我有帮助。结果,测试也明显更快。 我想你想要 Mongoid::Config.purge! Mongoid.purge! 适用于我的 4.0.2,我认为它比使用 DatabaseCleaner 更好。【参考方案4】:

其他答案都不适用于 Mongoid 3.0。我用@Batkins 的答案修改了这样

RSpec.configure do |config|

  # Clean/Reset Mongoid DB prior to running each test.
  config.before(:each) do
    Mongoid::Sessions.default.collections.select |c| c.name !~ /system/ .each(&:drop)
  end
end

或者,如果您想清空集合但又不想删除它(也许您有索引或其他东西),请执行此操作

Mongoid::Sessions.default.collections.select |c| c.name !~ /system/.each |c| c.find.remove_all

【讨论】:

对不起。我在没有看到您的答案的情况下评论了上面的回复。投票为Mongoid::Sessions.defaultMongoid.default_session 一样好。 @Alessandro - 谢谢,我不知道 Mongoid.default_session【参考方案5】:

恕我直言,这是一个比为清理数据库的特定目的安装 gem 更好的解决方案.... 3 行进入您的 spec_helper.rb:

RSpec.configure do |config|
  #Other config stuff goes here

  # Clean/Reset Mongoid DB prior to running the tests
  config.before :each do
    Mongoid.master.collections.select |c| c.name !~ /system/ .each(&:drop)
  end
end

信用:A user named Alex posted this as a solution for a similar question.

【讨论】:

如果您使用的是 Mongoid 3,您将需要类似:Mongoid.default_session.collections.select |c| c.name !~ /system/ .each(&:drop) 这完全是挑剔的,真的可能根本不重要,但您的解决方案效率有点低。您将遍历所有集合一次以进行选择,然后遍历每个集合中的子集。这只会对集合进行一次迭代:Mongoid.default_session.collections.each |coll| coll.drop unless /^system/.match(coll.name) 【参考方案6】:

如果您使用的是 MongoID,您可以将 Database Cleaner 与 Truncation 策略一起使用。例如:

RSpec.configure do |config|
  config.use_transactional_fixtures = false

  config.before :each do
    DatabaseCleaner.strategy = :truncation
    DatabaseCleaner.start
  end

  config.after do
    DatabaseCleaner.clean
  end
end

【讨论】:

以上是关于在 Rails 3 上使用 Rspec 和 MongoID 清理或重置测试数据库的主要内容,如果未能解决你的问题,请参考以下文章

在 Rails 3.1 中使用 Capybara、Rspec 和 Selenium 进行测试时登录失败

使用 Rspec 测试 Rails 3.1 可安装引擎

Rails 3,RSpec 2.5:使用带有命名范围的 should_receive 或 stub_chain

由于符号而不是 Rails 导致哈希失败的 RSpec 测试

在rails 2.3+中测试(rspec)嵌套模型部分

Rails 3.1,RSpec:测试模型验证