在 Ruby 中对类/方法进行非猴子修补
我正在尝试对我用 Ruby 编写的一段调用 File.open
的代码进行单元测试。为了模拟它,我将 File.open
修改为以下内容:
class File
def self.open(name, &block)
if name.include?("retval")
return "0\n"
else
return "1\n"
end
end
end
问题是我使用 rcov 来运行整个事情,因为它使用 File.open 写入代码覆盖率信息,它获取猴子补丁版本而不是真正的版本。 如何取消此方法的monkeypatch以将其恢复为原始方法?我尝试过使用alias
,但到目前为止没有效果。
I'm trying to unit test a piece of code that I've written in Ruby that calls File.open
. To mock it out, I monkeypatched File.open
to the following:
class File
def self.open(name, &block)
if name.include?("retval")
return "0\n"
else
return "1\n"
end
end
end
The problem is that I'm using rcov to run this whole thing since it uses File.open to write code coverage information, it gets the monkeypatched version instead of the real one. How can I un-monkeypatch this method to revert it to it's original method? I've tried messing around with alias
, but to no avail so far.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
扩展@Tilo的答案,再次使用别名来撤消猴子修补。
例子:
Expanding on @Tilo's answer, use alias again to undo the monkey patching.
Example:
或者您可以使用存根框架(如 rspec 或 mocha)并存根 File.Open 方法。
File.stub(:open => "0\n")
or you can use a stubbing framework (like rspec or mocha) and stub the File.Open method.
File.stub(:open => "0\n")
File
只是一个保存Class
实例的常量。您可以将其设置为响应open
的临时类,然后恢复原始类:File
is just a constant that holds an instance ofClass
. You could set it to a temporary class that responds toopen
, and then restore the original one:您可以简单地像这样别名:
例如:
现在您仍然可以通过 File.old_open 访问原始 File.open 方法
或者,您可以尝试这样的操作:
ruby - 覆盖方法然后恢复
http://blog.jayfields.com/2006/12/ruby-别名-方法-alternative.html
you can simply alias it like this:
e.g.:
now you can still access the original File.open method via File.old_open
Alternatively, you could try something like this:
ruby - override method and then revert
http://blog.jayfields.com/2006/12/ruby-alias-method-alternative.html
正确的方法是像 Dan 所说的那样实际使用存根框架。
例如,在 rspec 中,您可以这样做:
但出于好奇,这里有一种半安全的方法,无需外部库即可完成此操作。
这个想法是隔离存根,以便尽可能少的代码受其影响。
我将此脚本命名为
isolated-patch.rb
:演示:
The correct way to do this is to actually use a stubbing framework like Dan says.
For example, in rspec, you'd do:
But for the curious, here's a semi-safe way to do it without external libs.
The idea is to isolate the stub so as little code is affected by it as possible.
I named this script
isolated-patch.rb
:Demo: