【问题标题】:How to do proper database testing (TDD) on Rails 3 using MongoDB and Mongoid如何使用 MongoDB 和 Mongoid 在 Rails 3 上进行适当的数据库测试 (TDD)
【发布时间】: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)。

【问题讨论】:

    标签: ruby-on-rails testing mongodb persistence mongoid


    【解决方案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.

        【讨论】:

          猜你喜欢
          • 2011-09-28
          • 1970-01-01
          • 2011-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-12
          相关资源
          最近更新 更多