您可能想看看 Ruby 模拟框架,例如Mocha http://mocha.rubyforge.org/,但就使用普通 Ruby 而言,可以使用alias_method
(文档here http://ruby-doc.org/core/classes/Module.html#M001653) e.g.
预先:
class Thread
class << self
alias_method :old_current, :current
end
end
然后定义你的新方法
class Thread
def self.current
# implementation here
end
end
然后恢复旧方法:
class Thread
class << self
alias_method :current, :old_current
end
end
更新以说明在测试中执行此操作
如果您想在测试中执行此操作,您可以定义一些辅助方法,如下所示:
def replace_class_method(cls, meth, new_impl)
cls.class_eval("class << self; alias_method :old_#{meth}, :#{meth}; end")
cls.class_eval(new_impl)
end
def restore_class_method(cls, meth)
cls.class_eval("class << self; alias_method :#{meth}, :old_#{meth}; end")
end
replace_class_method
需要一个类常量、一个类方法的名称和一个字符串形式的新方法定义。restore_class_method
获取类和方法名称,然后将原始方法别名放回原位。
然后您的测试将类似于:
def test
new_impl = <<EOM
def self.current
"replaced!"
end
EOM
replace_class_method(Thread, 'current', s)
puts "Replaced method call: #{Thread.current}"
restore_class_method(Thread, 'current')
puts "Restored method call: #{Thread.current}"
end
您还可以编写一个小包装方法,该方法将替换一个方法,产生一个块,然后确保随后恢复原始方法,例如
def with_replaced_method(cls, meth, new_impl)
replace_class_method(cls, meth, new_impl)
begin
result = yield
ensure
restore_class_method(cls, meth)
end
return result
end
在您的测试方法中,这可以用作:
with_replaced_method(Thread, 'current', new_impl) do
# test code using the replaced method goes here
end
# after this point the original method definition is restored
正如原始答案中提到的,您可能可以找到一个框架来为您执行此操作,但希望上面的代码无论如何都是有趣且有用的。