Ruby 伪造没有db的活动记录模型

Ruby 伪造没有db的活动记录模型,ruby,testing,activerecord,gem,Ruby,Testing,Activerecord,Gem,我觉得我错过了什么。我正在编写一个RubyGem,它允许与ActiveRecord交互,作为其主要功能的附加组件 在为其编写测试用例时,我需要能够指定虚拟活动记录模型来测试此功能。如果我能得到一个活动记录模型的实例,它不需要任何数据库连接,它可以有关系,所有这些东西,但不需要我在数据库中设置表,那就太棒了。我对测试还比较陌生,在rails测试之外,我还很新鲜,但看起来我应该可以很容易地做类似的事情,但我什么也没发现 谁能告诉我我错过了什么?我看过工厂、制造商、固定装置,所有这些似乎都想达到db。

我觉得我错过了什么。我正在编写一个RubyGem,它允许与ActiveRecord交互,作为其主要功能的附加组件

在为其编写测试用例时,我需要能够指定虚拟活动记录模型来测试此功能。如果我能得到一个活动记录模型的实例,它不需要任何数据库连接,它可以有关系,所有这些东西,但不需要我在数据库中设置表,那就太棒了。我对测试还比较陌生,在rails测试之外,我还很新鲜,但看起来我应该可以很容易地做类似的事情,但我什么也没发现


谁能告诉我我错过了什么?我看过工厂、制造商、固定装置,所有这些似乎都想达到db。在您只需要AR对象进行测试的情况下,人们如何测试宝石?

其他人也遇到了同样的问题。我通常的做法是使用模拟库进行单元测试,并使用fixture编写一些功能库,以补充那些过于复杂而无法模拟的设置(您应该避免使用任何方法)

或者使用AR的替换库,该库提供相同的接口,但不需要DB。我已经有一段时间没有使用rails了,但是以前有一些可用的。这并非完全没有与最初使用DB相同的问题,因为这些库通常有其他需求(如web服务、LDAP等),或者只需要与Mock相同的单记录设置工作


或者咬紧牙关,只使用固定装置,但通过使用内存中的sqlite DB进行测试和适当的迁移,使它们的成本非常小。

是的,我想在Rails 2.3中做一段时间,这是一个非常令人头痛的问题。我认为现在使用ActiveModel会更容易,如果您想自己开发,它会为您提供一个明确的接口

另外,我自己也没有用过它,但是Josh Susser有一个宝石,可以让你在任何类中混合类似AR的行为。它似乎倾向于在表单中使用普通的ruby对象,但对于单元测试可能也很有用。看

他在最近的一篇文章中谈到了这一点,听起来你需要:

NullDB是应用于ActiveRecord数据库适配器的空对象模式。它是一个数据库后端,将数据库交互转换为无操作。使用NullDB使您能够测试您的模型业务逻辑(包括保存挂钩之后的逻辑),而无需接触真实的数据库


另一种选择是使用sqlite3适配器并在内存中运行数据库,并在测试后使用DatabaseCleaner清除记录

这种方法有某些优点:

  • 您可以在测试中看到SQL,它简化了查询优化过程
  • 这是接近“现实生活”的例子
另一方面,我应该说它有点凌乱,因为它有点长,但可以随意重组;)

以下是您对此所需的简要说明:

# in Gemfile
gem "activerecord" #since you are dealing with activerecord
gem "database_cleaner", :group => :test
gem "sqlite3", :group => :test
我使用以下方法保留该内容,但欢迎您使用不同的方式:

# in RAILS_ROOT/test/support/active_record.rb
require 'logger'

ActiveRecord::Base.establish_connection(
  :adapter => "sqlite3", :database => ':memory:'
)

#this line will print the SQL queries right into console 
ActiveRecord::Base.logger = Logger.new(STDOUT)

# in RAILS_ROOT/test/support/database_cleaner.rb
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
# or DatabaseCleaner.strategy = :trunsaction (it is up to you)

module OrmSetup
  def before_setup
    DatabaseCleaner.start
  end

  def after_teardown
    DatabaseCleaner.clean
  end
end

# in RAILS_ROOT/test/test_helper.rb
...
require File.expand_path("support/active_record", File.dirname(__FILE__))
require File.expand_path("support/database_cleaner", File.dirname(__FILE__))

class Test::Unit::TestCase
  include OrmSetup
end
现在在你的测试中,你可以得到

require 'test_helper'

class User < ActiveRecord::Base
end

class MyFancyTest < Test::Unit::TestCase
  def setup
    before_setup
  end

  def teardown
    after_teardown
  end
end
需要“测试助手”
类用户
这正是我想要的。谢谢这个库的一个缺点是它与Rspec的耦合方式。如果你不使用rspec,你需要记住的是,你的观点是正确的。一个很小的sqlite数据库将是一个很好的选择。非正式的看起来很酷。事实上,我可能会用这个来做其他事情,谢谢你指出这一点。