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
这将使您调用这些方法,而不会影响该类的其他对象。您可以在测试目录中重新打开该类,并将其对测试代码中的所有实例公开,但这可能会影响对公共接口的测试。