Ruby Rspec: Testen von Instanzvariablen ohne Hinzufügen eines Accessors zur Quelle

79

Ich versuche die folgende Methode zu testen:

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

Hier möchte ich den Status für @multi_move festlegen, aber ich möchte keinen Accessor nur zum Testen hinzufügen. Gibt es eine Möglichkeit, dies ohne den Accessor zu tun? Vielen Dank.

steve_gallagher
quelle

Antworten:

131

Sie können die Object#instance_variable_getMethode verwenden, um den Wert einer beliebigen Instanzvariablen des Objekts wie folgt abzurufen:

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

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

Und Object#instance_variable_setkann verwendet werden, um Instanzvariablenwerte festzulegen:

foo.instance_variable_set(:@foo, 12) 
puts foo.instance_variable_get(:@foo)
#=> 12
KL-7
quelle
Aber ich muss es vorher in meinem Test einstellen. Es hat keinen Wert, bevor ich es teste.
steve_gallagher
1
@steve_gallagher, schauen Sie sich die Dokumente an. Es gibt instance_variable_setdirekt neben instance_variable_get(Beispiel hinzugefügt und Link zu den Dokumenten zur Antwort).
KL-7
1
Interessant. Ich wusste nicht, dass Sie einfach hineingehen und eine solche Instanzvariable festlegen und abrufen können. Ich habe jedoch viele RSpec-Tests gesehen, und ich habe diese Methoden nie aufgerufen gesehen. Scheint eine nicht standardmäßige Art zu sein, mit dem umzugehen, was ich für eine ziemlich typische Situation halte. Ich beschwere mich jedoch nicht, danke für die Antwort.
steve_gallagher
17
@steve_gallagher, ich denke, der Grund, warum Sie das noch nie gesehen haben, ist, dass der private Status eines Objekts in den meisten Fällen nicht das ist, was Sie testen sollten. Wenn Sie das Verhalten und die Logik eines Objekts testen möchten, sollten Sie testen, was es tut, aber nicht, wie es funktioniert. Wenn Sie keinen öffentlichen Zugriff auf eine Instanzvariable gewähren (z. B. in Ihrem Fall keinen Getter dafür definieren), muss sich niemand außerhalb des Objekts um seinen Status kümmern, solange sich das Objekt so verhält, wie es sollte. In Ihrem Fall ist es vielleicht besser, das Ergebnis zu testen, als die Tatsache, dass eine Instanzvariable festgelegt wurde.
KL-7
2
Ihre Erklärung wird sehr geschätzt, wenn Sie sie jetzt aus einer anderen Perspektive betrachten. Ich weiß nicht, warum ich das vorher nicht bemerkt habe. Natürlich muss ich sie umgestalten, damit die Instanzvariable nicht gesetzt werden muss, um das zu beweisen Methode funktioniert. Danke noch einmal.
steve_gallagher