情景我已经提取了一个名为关注 Taggable
。 这是一个模块,允许任何模型来支持标记。 我已经包含了这种担忧/模块到像模特User
, Location
, Places
, Projects
。
我想写这个模块的测试,但不知道从哪里开始。
题
1.我可以做隔离测试上Taggable
的关注?
在测试下面的例子,因为测试正在寻找失败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
我的一部分想,如果我只是测试已经包括它里面这个模块像模特User
这足够测试的。 但我继续阅读,你应该在隔离测试模块。
寻找在正确的方法是什么的一些指导/战略。
我建议有DummyClass
是通用ActiveRecord::Base
孩子用很少的自定义代码除了刚才include Taggable
,这样你会被隔离您的关心模块尽可能多的,但仍然是一个AR类。 避免使用喜欢你的“真正的”类之一的User
仍然在这些类中的任何其他代码,这似乎是有价值的隔离你。
因此,像这样:
class DummyClass < ActiveRecord::Base; end
describe Taggable do
before do
@dummy_class = DummyClass.new
end
...
end
由于您的DummyClass
可能需要实际与DB测试之类的社团互动,你可能需要在测试期间创建数据库临时表。 该临时工红宝石宝石也许能够帮助是,因为它的设计,创建临时的ActiveRecord模型和它们的底层数据库表。
临时工允许您创建通过在试验中使用的临时SQL表支持任意的ActiveRecord模型。 您可能需要,如果你正在测试,是为了混入ActiveReord车型没有中继上一个具体的类模块做这样的事情。
我去使用ActiveRecord的无表 ,而不是在做临时工的宝石,这似乎是过时的时刻了一点出来。
我建立了我的测试了完全一样的司徒中号在他的答案 ,但包括has_no_table
我DummyClass所需的辅助方法和列。
class DummyClass < ActiveRecord::Base
# Use ActiveRecord tableless
has_no_table
# Add table columns
column :name, :string
# Add normal ActiveRecord validations etc
validates :name, :presence => true
end
这个工作对我需要测试,这是扩展模块什么ActiveRecord::Base
有几个方法,但我还没有与任何尝试过has_many
关联,以便它仍然可能无法与你想考什么帮助。
这是我类似的问题的解决方案:
describe Taggable do
subject { mock_model('User').send(:extend, Taggable) }
it { should have_many(:tags) }
...
describe "#tag" do
...
end
end
事实上mock_model('User')
可以模拟系统中的任何存在的模型。
这不是一个理想的解决方案,但至少它是明确和嘲笑一切。
注意 : mock_model
(AR嘲笑)提取到rspec的-activemodel的-嘲笑在rspec的3.0。
另外你需要使用早该-匹配器的匹配器的关联。
正如@ StuartM建议的答案 ,使用临时工宝石为我工作:
# test.rb/spec.rb
Temping.create :dummy_class do
include Taggable
end
describe Taggable do
before do
@dummy = DummyClass.new
end
...
end