Ruby Rspec: тестирование переменных экземпляра без добавления средства доступа к источнику

Я пытаюсь протестировать следующий метод:

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, но я не хочу добавлять аксессор только для тестирования. Есть ли способ сделать это без аксессуара? Спасибо.


person steve_gallagher    schedule 20.02.2012    source источник


Ответы (1)


Можно использовать метод 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
person KL-7    schedule 20.02.2012
comment
Но мне нужно заранее установить его в моем тесте. Пока я не тестирую, он не имеет значения. - person steve_gallagher; 20.02.2012
comment
@steve_gallagher, взгляни на документацию. Рядом с instance_variable_get есть instance_variable_set (добавлен пример и ссылка на документацию к ответу). - person KL-7; 20.02.2012
comment
Интересно. Я не знал, что вы можете просто пойти и установить и получить любую подобную переменную экземпляра. Тем не менее, я видел много тестов RSpec и никогда не видел, чтобы эти методы вызывались. Похоже на нестандартный способ справиться с тем, что, на мой взгляд, было бы довольно типичной ситуацией. Но я не жалуюсь, спасибо за ответ. - person steve_gallagher; 20.02.2012
comment
@steve_gallagher, я думаю, причина, по которой вы не видели этого раньше, заключается в том, что частное состояние объекта - это не то, что вы должны тестировать в большинстве случаев. Если вы стремитесь проверить поведение и логику какого-либо объекта, вам следует проверить, что он делает, а не как. Если вы не предоставляете публичный доступ к некоторой переменной экземпляра (например, не определяете для нее геттер в вашем случае), нет необходимости, чтобы кто-то за пределами объекта заботился о его состоянии, пока объект ведет себя должным образом. В вашем случае, возможно, лучше проверить результат, а не тот факт, что была установлена ​​некоторая переменная экземпляра. - person KL-7; 20.02.2012
comment
Ваше объяснение очень ценится, глядя на него сейчас с другой точки зрения, я не знаю, почему я не заметил этого раньше, очевидно, мне нужно его реорганизовать, чтобы переменную экземпляра не нужно было устанавливать, чтобы доказать, что метод работает. Спасибо еще раз. - person steve_gallagher; 21.02.2012