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()
, что также даст вам доступ к закрытым и защищенным методам (как предложил Джеймс Бейкер)
Кроме того, вы можете изменить метакласс вашего тестового объекта, чтобы сделать приватные / защищенные методы общедоступными только для этого объекта.
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
Это позволит вам вызывать эти методы, не затрагивая другие объекты этого класса.
Вы можете открыть класс в вашем тестовом каталоге и сделать его общедоступным для всех
экземпляры в вашем тестовом коде, но это может повлиять на ваш тест открытого интерфейса.