ruby 伪造不带数据库的活动记录模型

m0rkklqb  于 2023-03-17  发布在  Ruby
关注(0)|答案(5)|浏览(115)

我觉得我错过了一些东西,我正在写一个ruby gem,它允许与活动记录交互,作为其主要功能的一个附加功能。
在为它编写测试用例时,我需要能够指定虚拟的活动记录模型来测试这个功能。如果我能得到一个活动记录模型的示例,它不需要任何到数据库的连接,可以有关系,所有的东西,但不需要我在数据库中设置表,那将是极好的。我是一个相当新的测试,除了rails测试之外,我是相当新的。但看起来我应该可以很容易地做这样的事情,但我什么也没找到。
有人能告诉我我错过了什么吗?我已经看了工厂,制造商,夹具,所有这些似乎都想击中数据库。人们如何测试宝石,你需要AR对象只是为了测试?

w8ntj3qf

w8ntj3qf1#

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

kupeojn6

kupeojn62#

其他人也遇到了同样的问题。我通常采取的做法是使用模拟库进行单元测试,并使用fixture编写一些函数库,以补充过于复杂而无法模拟的设置(无论如何都应该避免)。
或者使用AR的替代库,它提供相同的接口,但不需要DB。我已经有一段时间没有使用Rails了,但曾经有一些可用的。这并不是完全没有使用DB的问题,因为这些库通常有其他的需求(如Web服务,LDAP,...),或者只是需要与模拟相同的单记录设置工作。
或者咬紧牙关,只使用fixture,但通过使用内存中的sqlite DB只用于测试和适当的迁移,使它们的成本非常小。

cbeh67ev

cbeh67ev3#

是的,我想在Rails2.3中做这件事,这是一个巨大的嘲笑头痛。我认为现在有了ActiveModel更容易,它给了你一个显式的接口,如果你想自己滚动的话。
另外,我自己也没有用过,但是Josh Susser有一个gem,可以让你把AR风格的行为混合到任何类中。它似乎适合在窗体中使用普通的ruby对象,但它可能对单元测试也很有用。参见informal
他在最近的Ruby Rogues episode中谈到了这一点

xdyibdwo

xdyibdwo4#

另一种选择是使用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
t9aqgxwy

t9aqgxwy5#

Active Entity。它支持属性和验证。它似乎不像AR那样支持关系,但是有embeds_oneembeds_many方法提供了类似的功能。它似乎是AR在测试中的一个不错的替代品,而不依赖于数据库。
我能够在我的rspec测试中使用它作为ActiveRecord的替代。
在RSpec测试中,我这样使用它:

before do
  stub_const('TestModel', Class.new(ActiveEntity::Base))
  TestModel.attribute :my_prop, :string
end

let(:record) { TestModel.new(my_prop: 'abcdef') }
subject { MyService.call(record) }

it { is_expected.to eq('...') }

相关问题