我有一个类似于ActiveRecord的父类,我正试图在我们的测试套件中打开这个类。我想包装initialize
方法,以便它维护一个初始化的所有子类的列表,这样我就可以确保在测试之间清理这些类的所有数据。在测试之间运行完全擦除会导致效率太低(而且我只是对代码想要执行此操作感兴趣)。
我的目标是在继承树中插入新的initialize
方法,然后调用super
。一直在维护父类中所有实例化类的一些列表。
到目前为止我的尝试:
class NewActiveRecord
@@__instantiated_classes = Set.new
def initialize(*args)
@@__instantiated_classes.add(self.class)
super *args
end
def self.reset_tracking
@@__instantiated_classes = Set.new
end
def self.get_instantiated_classes
@@__instantiated_classes.to_a
end
end
class ActiveSupport::TestCase
teardown do
NewActiveRecord.get_instantiated_classes.each {|c| c.destroy_all}
NewActiveRecord.reset_tracking
end
end
基本上我想包装所有在某些父类的子类上调用的方法,将它们的类发送到某个预定义对象的类
答案 0 :(得分:0)
今天做了一些探索并提出了以下解决方案。我仍然不确定如何解开一些东西但是:
module Spy
def self.on_instance_method(mod, method, &block)
mod.class_eval do
# Stash the old method
old_method = instance_method(method)
# Create a new proc that will call both our block and the old method
proc = Proc.new do
block.call if block
old_method.bind(self).call
end
# Bind that proc to the original module
define_method(method, proc)
end
end
def self.on_class_method(mod, method, &block)
mod.class_eval do
# Stash the old method
old_method = singleton_method(method)
# Create a new proc that will call both our block and the old method
proc = Proc.new do
block.call if block
old_method.call
end
# Bind that proc to the original module
define_singleton_method(method, proc)
end
end
end
我的测试用法如下:
count = 0
Spy.on_instance_method(FakeClass, :value) { count += 1 }
fake = FakeClass.new(6)
fake.value.must_equal 6
count.must_equal 1