Подтвердить что ты не робот

Как установить переменную частного экземпляра, используемую в тесте метода?

Учитывая класс с несколькими переменными экземпляра и некоторыми методами. Некоторые переменные экземпляра доступны через attr_reader и attr_accessor. Таким образом, остальные частные. Некоторые из переменных частного экземпляра устанавливаются в одном из методов экземпляра и считываются/используются в рамках другого метода.

Для тестирования я использую RSpec. Поскольку я еще новичок в Ruby и хочу, чтобы все было правильно, я определил, что мои тесты довольно мелкозернистые. Таким образом, у меня есть один блок describe для каждого метода экземпляра, который сам разбит на подмножество context и it s. Общие предварительные условия окружающей среды определяются с помощью before.

Однако при тестировании одного из методов, который использует, но не устанавливает одну из частных переменных, мне нужно вызвать другой метод, который устанавливает эту переменную. Это кажется избыточным весом, а не модульным для меня.

Есть ли способ принудительного преобразования переменной частного экземпляра в определенное значение. Подобно "вырыванию" значения переменной частного экземпляра с Object::instance_eval(:var).

4b9b3361

Ответ 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