问题描述
|
我有一个扩展ActiveSupport :: Concern的模块。这是“ 0”块:
included do
after_save :save_tags
has_many :taggings,:as => :taggable
has_many :tags,:through => :taggings
end
我该如何处理这些电话?我尝试了几种方法,但是Ruby抱怨当我单独测试模块时这些方法不存在。
谢谢!
解决方法
我认为您有两种选择,具体取决于要测试的内容。
如果只想测试该模块是否实际设置了
has_many
关联和after_save
回调,则可以设置一个简单的rspec期望值:
class Dummy
end
describe Taggable do
it \"should setup active record associations when included into models\" do
Dummy.should_receive(:has_many).twice
Dummy.should_receive(:after_save).with(:save_tags)
Dummy.send(:include,Taggable) # send is necessary because it\'s a private method
end
end
您可能可以很容易地测试save_tags
方法,而无需进行进一步的模拟,但是如果您要测试依赖于has_many关联被设置的行为,则可以创建另一个具有has_many和after_save的Dummy类,但需要使用关联的访问器:
class Dummy
attr_accessor :taggings,:tags
# stub out these two
def self.has_many
end
def self.after_save
end
def initialize
@taggings = []
@tags = []
end
include Taggable
end
describe Taggable do
it \"should provide a formatted list of tags,or something\" do
d = Dummy.new
d.tags = [double(\'tag\')]
d.formatted_tags.size.should == 1
end
end
我们可以通过一些元编程来清理(有些脆弱的测试类),尽管这取决于您是否认为这会使测试太难理解。
class Dummy
def self.has_many(plural_object_name,options={})
instance_var_sym = \"@#{plural_object_name}\".to_sym
# Create the attr_reader,setting the instance var if it doesn\'t exist already
define_method(plural_object_name) do
instance_variable_get(instance_var_sym) ||
instance_variable_set(instance_var_sym,[])
end
# Create the attr_writer
define_method(\"#{plural_object_name}=\") do |val|
instance_variable_set(instance_var_sym,val)
end
end
include Taskable
end
, 在开始测试之前,您需要确保首先使用ActiveSupport :: Concern的原始定义加载文件,并且在加载之后必须加载扩展。确保加载正确的文件,因为rails自动加载机制将使您的扩展更适合原始文件。