gpt4 book ai didi

ruby-on-rails - ruby : Alter class static method in a code block

转载 作者:行者123 更新时间:2023-12-04 06:15:12 25 4
gpt4 key购买 nike

给定 Thread 类及其当前方法。现在在测试中,我想这样做:

def test_alter_current_thread
Thread.current = a_stubbed_method
# do something that involve the work of Thread.current
Thread.current = default_thread_current
end

基本上,我想更改测试方法中类的方法,然后恢复它。我知道这对于另一种语言来说听起来很复杂,比如 Java 和 C#(在 Java 中,只有强大的模拟框架才能做到)。但它是 ruby ,我希望这样令人讨厌的东西能够被使用

最佳答案

您可能想看一下 Ruby 模拟框架,例如 Mocha ,但就使用普通 Ruby 而言,可以使用 alias_method (文档 here )来完成,例如

事前:

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

您还可以编写一个小包装方法,该方法将替换一个方法,产生一个 block ,然后确保随后恢复原始方法,例如

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

正如原始答案中提到的,您可能可以找到一个框架来为您执行此操作,但希望上面的代码无论如何都是有趣且有用的。

关于ruby-on-rails - ruby : Alter class static method in a code block,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3014048/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com