如何使用 MongoDB 和 Mongoid 在 Rails 3 上进行适当的数据库测试 (TDD)

Posted

技术标签:

【中文标题】如何使用 MongoDB 和 Mongoid 在 Rails 3 上进行适当的数据库测试 (TDD)【英文标题】:How to do proper database testing (TDD) on Rails 3 using MongoDB and Mongoid 【发布时间】:2011-06-08 22:58:42 【问题描述】:

如何通过 Mongoid on Rails 使用 MongoDB 编写适当的单元测试(以及集成测试)?

我在问,因为与使用 SQLite3 相反,即使在运行测试时,我所做的一切都会持续存在。所以目前我正在编写创建测试,然后我手动删除我所做的一切。但是对于集成测试来说,它变得越来越烦人甚至变得复杂。

我所做的示例:

before(:each) do
  @user = User.create!(@attr)
end

after(:each) do
  # MongoDB is not a transactional DB, so added objects (create) during tests can't be rollbacked
  # checking for the existance of a similar object with exact :name and :email (regex make it case insensitive)
  cleanup = User.where(:name => "Example User", :email => /^user@example.com/i)
  cleanup.destroy unless cleanup.nil?
end

知道如何在测试期间使 MongoDB 不持久吗? (我什至不能在沙盒模式下运行控制台,因为要使用 Mongoid 我必须停用 Active Record)。

【问题讨论】:

【参考方案1】:

没有办法让 MongoDB 非持久化。您只需在每次测试之前或之后删除数据。这里有一些文档:

http://www.mongodb.org/display/DOCS/Rails+-+Getting+Started#Rails-GettingStarted-Testing

【讨论】:

谢谢,这就是我害怕的......虽然很好的链接,我想我已经阅读了完整的 mongoDB 页面,但显然还没有:) 我会尝试这个解决方案以避免不得不每次编写测试时添加手动代码。【参考方案2】:

好的,感谢 Kyle 为我指明了正确的方向,我知道了如何让它发挥作用。

因此,基本上诀窍是为您将运行的每个测试用例删除 mongodb 中的所有集合。这有点激进,但它确实有效。但请记住,您根本不会在测试数据库中保留任何数据。

终于找到了那个链接:http://adventuresincoding.com/2010/07/how-to-configure-cucumber-and-rspec-to-work-with-mongoid

基本上你需要做的很简单:

在你的 spec_helper.rb 中添加一个块:

RSpec.configure do |config|

# blabla other confs

  config.before :each do
    Mongoid.master.collections.select |c| c.name !~ /system/ .each(&:drop)
  end

# blabla other confs

end

对于 Mongoid 3:

 Mongoid.default_session.collections.select |c| c.name !~ /system/ .each(&:drop

这有效地杀死了数据库中的所有集合,让您每次都能重新运行测试。

亚历克斯

【讨论】:

mongoid 文档也涵盖了这一点。您还可以使用 database_cleaner gem mongoid.org/docs/integration 谢谢。这比不必担心专门用于清理数据库的 gem 要好得多哈哈。 @Christos,您提到的链接已损坏。 请注意,如果您使用的是 Mongoid 3,您将需要类似:Mongoid.default_session.collections.select |c| c.name !~ /system/ .each(&:drop) 没有方便的方法自动调用“rake db:drop”吗?【参考方案3】:

另一种方法是使用database_cleaner。它支持多个 ORM,所以我认为你可以这样做:

# spec/support/database_cleaner.rb
RSpec.configure do |config|
  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
end

【讨论】:

【参考方案4】:

这就是我所做的(使用 Test::Unit 和 Mongoid 3)...

# test/test_helper.rb
setup 
  Mongoid.default_session.collections.select |c| c.name !~ /system/ .each(&:drop)

【讨论】:

【参考方案5】:

这个对我有用。

spec_helper.rbRSpec.configure do |config| 我放了:

config.before :each do
   Mongoid.purge!
end

Reference.

【讨论】:

以上是关于如何使用 MongoDB 和 Mongoid 在 Rails 3 上进行适当的数据库测试 (TDD)的主要内容,如果未能解决你的问题,请参考以下文章

如何实现has_many:通过与Mongoid和mongodb的关系?

如何使用 Mongoid 查看原始 mongoDB 查询

批量查找 mongoDB 记录(使用 mongoid ruby​​ 适配器)

如何在 Mongoid / MongoDB 中为 $within 查询选择单位

如何避免在 MongoDB(使用 Mongoid)或 ActiveRecord(使用 MySQL 的 Rails)中插入两次相同的记录?

使用 Mongoid 的 MongoDB 对话/私人消息模式