instance_eval()
可能有帮助:
--------------------------------------------------- Object#instance_eval
obj.instance_eval(string [, filename [, lineno]] ) => obj
obj.instance_eval {| | block } => obj
------------------------------------------------------------------------
Evaluates a string containing Ruby source code, or the given
block, within the context of the receiver (obj). In order to set
the context, the variable self is set to obj while the code is
executing, giving the code access to obj's instance variables. In
the version of instance_eval that takes a String, the optional
second and third parameters supply a filename and starting line
number that are used when reporting compilation errors.
class Klass
def initialize
@secret = 99
end
end
k = Klass.new
k.instance_eval { @secret } #=> 99
您可以使用它直接访问私有方法和实例变量。
您也可以考虑使用send()
,它还可以让您访问私有和受保护的方法(就像 James Baker 建议的那样)
或者,您可以修改测试对象的元类,使私有/受保护的方法仅为该对象公开。
test_obj.a_private_method(...) #=> raises NoMethodError
test_obj.a_protected_method(...) #=> raises NoMethodError
class << test_obj
public :a_private_method, :a_protected_method
end
test_obj.a_private_method(...) # executes
test_obj.a_protected_method(...) # executes
other_test_obj = test.obj.class.new
other_test_obj.a_private_method(...) #=> raises NoMethodError
other_test_obj.a_protected_method(...) #=> raises NoMethodError
这将允许您调用这些方法而不会影响该类的其他对象。您可以在测试目录中重新打开该类,并将它们公开给您的测试代码中的所有实例,但这可能会影响您对公共接口的测试。