Ruby Rspec: Тестування змінних екземпляра без додавання доступу до джерела


79

Я намагаюся перевірити наступний метод:

def unprocess_move(board, move)
  if move[0].instance_of?(Array)
    multi_move = @multi_move.pop(2).reverse
    multi_move.each do |single_move|
      unapply_move(board, single_move)
    end
  else
    board = unapply_move(board, move)
  end
  board
end

де я хочу встановити стан для @multi_move, але я не хочу додавати аксесуар лише для тестування. Чи можна це зробити без аксесуара? Дякую.

Відповіді:


131

Ви можете використовувати Object#instance_variable_getметод, щоб отримати значення будь-якої змінної екземпляра об'єкта так:

class Foo 
  def initialize
    @foo = 5 # no accessor for that variable
  end 
end

foo = Foo.new
puts foo.instance_variable_get(:@foo)
#=> 5

І Object#instance_variable_setможе використовуватися для встановлення значень змінних екземпляра:

foo.instance_variable_set(:@foo, 12) 
puts foo.instance_variable_get(:@foo)
#=> 12

Але мені потрібно встановити це заздалегідь в рамках мого тесту. Він не має значення, перш ніж я його перевірю.
steve_gallagher

1
@steve_gallagher, погляньте на документи. Там є instance_variable_setпоруч із instance_variable_get(доданий приклад та посилання на документи до відповіді).
KL-7,

1
Цікаво. Я не знав, що ти можеш просто зайти і встановити та отримати будь-яку подібну змінну. Однак я бачив багато тестувань RSpec, і ніколи не бачив, щоб ці методи викликалися. Здається нестандартним способом поводження з тим, що, на мою думку, було б досить типовою ситуацією. Однак я не скаржусь, дякую за відповідь.
steve_gallagher

17
@steve_gallagher, я думаю, що причина, чому ви цього раніше не бачили, полягає в тому, що приватний стан об'єкта - це не те, що ви повинні перевіряти в більшості випадків. Якщо ви прагнете перевірити поведінку та логіку якогось об'єкта, ви повинні перевірити, що він робить, але не як це робить. Якщо ви не надаєте загальнодоступний доступ до якоїсь змінної екземпляра (наприклад, у вашому випадку не визначаєте getter для неї), немає потреби комусь за межами об’єкта дбати про його стан, поки об’єкт поводиться так, як слід. У вашому випадку, можливо, краще протестувати результат, а не той факт, що була встановлена ​​якась змінна екземпляра.
KL-7,

2
Ваше пояснення дуже вдячне, дивлячись на нього зараз з іншої точки зору, я не знаю, чому я цього не помічав раніше, явно мені потрібно його рефакторингувати, щоб змінну екземпляра не потрібно було встановлювати для доказування метод працює. Знову дякую.
steve_gallagher
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.