测试使用ActiveRecord的问题/模块

ale*_*enm 14 ruby unit-testing ruby-on-rails activesupport minitest

情景 我已经提到了一个叫做的问题Taggable.它是一个允许任何模型支持标记的模块.我已经包含了这种担忧/模块到像模特User,Location,Places,Projects.

我想为这个模块编写测试,但不知道从哪里开始.

问题
1.我可以对此Taggable问题进行隔离测试吗?
在下面的示例中,测试失败,因为测试正在寻找a dummy_class table.我假设它正在这样做因为has_many代码,Taggable因此它期望'DummyClass'是一个ActiveRecord对象.

# /app/models/concerns/taggable.rb
module Taggable
  extend ActiveSupport::Concern

  included do
    has_many :taggings, :as => :taggable, :dependent=> :destroy
    has_many :tags, :through => :taggings
  end

  def tag(name)
    name.strip!
    tag = Tag.find_or_create_by_name(name)
    self.taggings.find_or_create_by_tag_id(tag.id)
  end
end


# /test/models/concerns/taggable_test.rb
require 'test_helpers'

class DummyClass
end

describe Taggable do
  before do
    @dummy = DummyClass.new
    @dummy.extend(Taggable)
  end

  it "gets all tags" do
    @dummy.tag("dummy tag")
    @dummy.tags.must_be_instance_of Array
  end
end
Run Code Online (Sandbox Code Playgroud)

我的一部分认为,如果我只测试一个包含此模块的模型,就像User测试一样.但我一直在读,你应该单独测试模块.

寻找关于正确方法的一些指导/策略.

Stu*_*t M 6

我建议DummyClass成为一个ActiveRecord::Base只有很少自定义代码的普通孩子include Taggable,这样你就可以尽可能地隔离你的关注模块,但仍然是一个AR类.避免使用你的"真正"类之一,User仍然会将你与这些类中的任何其他代码隔离开来,这看起来很有价值.

所以像这样:

class DummyClass < ActiveRecord::Base; end

describe Taggable do
  before do
    @dummy_class = DummyClass.new
  end
  ...
end
Run Code Online (Sandbox Code Playgroud)

由于您DummyClass可能需要实际与DB交互以测试关联等事物,因此您可能需要在测试期间在DB中创建临时表.该临时工红宝石宝石也许能够帮助是,因为它的设计,创建临时的ActiveRecord模型和它们的底层数据库表.

Temping允许您创建由临时SQL表支持的任意ActiveRecord模型,以便在测试中使用.如果您正在测试一个混合到ActiveReord模型中的模块而不转发具体类,则可能需要执行此类操作.

  • 所以我之前确实尝试过你的方法,但是当我运行测试时,它一直认为我有一个“dummy_classes”表。ActiveRecord::StatementInvalid:找不到表“dummy_classes” (2认同)