Как установить переменную частного экземпляра, используемую в тесте метода?
Учитывая класс с несколькими переменными экземпляра и некоторыми методами. Некоторые переменные экземпляра доступны через attr_reader
и attr_accessor
. Таким образом, остальные частные.
Некоторые из переменных частного экземпляра устанавливаются в одном из методов экземпляра и считываются/используются в рамках другого метода.
Для тестирования я использую RSpec. Поскольку я еще новичок в Ruby и хочу, чтобы все было правильно, я определил, что мои тесты довольно мелкозернистые. Таким образом, у меня есть один блок describe
для каждого метода экземпляра, который сам разбит на подмножество context
и it
s. Общие предварительные условия окружающей среды определяются с помощью before
.
Однако при тестировании одного из методов, который использует, но не устанавливает одну из частных переменных, мне нужно вызвать другой метод, который устанавливает эту переменную. Это кажется избыточным весом, а не модульным для меня.
Есть ли способ принудительного преобразования переменной частного экземпляра в определенное значение. Подобно "вырыванию" значения переменной частного экземпляра с Object::instance_eval(:var)
.
Ответы
Ответ 1
Как вы ответили в своем вопросе, самый простой способ установить переменную экземпляра - это метод instance_eval
:
obj.instance_eval('@a = 1')
Другой способ - использовать instance_variable_set:
obj.instance_variable_set(:@a, 1)
Но я бы не рекомендовал делать это в ваших спецификациях. Спецификации относятся к тестированию поведения объекта и тестированию поведения путем разбивки инкапсуляции класса с помощью instance_eval
, что сделает ваши тесты более хрупкими и зависимыми от реализации.
Альтернативный подход к изоляции состояния объекта - это методы доступа к заглушке:
class UnderTest
attr_accessor :a
def test_this
do_something if a == 1
end
end
#in your test
under_test = UnderTest.new
under_test.stub(:a).and_return(1)
Ответ 2
Используйте instance_variable_set
:
class SomeClass
attr_reader :hello
def initialize
@hello = 5
end
# ...
end
a = SomeClass.new
a.hello # => 5
a.instance_variable_set("@hello", 7)
a.hello # => 7
Ответ 3
Я просто решил это, создав дочерний элемент и добавив метод доступа:
class HasSecrets
@muahaha
end
class TestMe < HasSecrets
attr_accessor(:muahaha)
end
def test_stuff
pwned = TestMe.new()
pwned.muahaha = 'calc.exe'
end