Comment définir une variable d’instance privée utilisée dans un test de méthode?

Étant donné une classe avec quelques variables d’instance et certaines méthodes. Certaines variables d’instance sont accessibles via attr_reader et attr_accessor . Ainsi les autres sont privés.
Certaines des variables d’instance privées sont définies dans l’une des méthodes d’instance et lues / utilisées dans une autre méthode.

Pour tester, j’utilise RSpec. Comme je suis encore nouveau chez Ruby et que je veux tout régler correctement, j’ai défini mes tests comme étant plutôt fins. J’ai donc un bloc describe pour chaque méthode d’instance, eux-mêmes partitionnés en un sous-ensemble de context s. Les conditions environnementales générales préalables sont définies avec before .

Toutefois, lorsque vous testez l’une des méthodes, qui utilise mais ne définit pas l’une des variables privées, je dois appeler l’autre méthode, qui définit cette variable. Cela semble plutôt excessif et non modulaire pour moi.

Est-il possible de forcer une variable d’instance privée à une certaine valeur? Semblable à ” extraire ” la valeur d’une variable d’instance privée avec Object::instance_eval(:var) .

Comme vous avez répondu dans votre question, la méthode la plus simple pour définir la variable d’ instance_eval méthode instance_eval :

 obj.instance_eval('@a = 1') 

Une autre méthode consiste à utiliser instance_variable_set:

 obj.instance_variable_set(:@a, 1) 

Mais je ne recommanderais pas de le faire dans vos spécifications. Les spécifications concernent tout le test du comportement d’un object et le comportement de test en interrompant l’encapsulation de classe avec instance_eval rendra vos tests plus fragiles et dépendants de l’implémentation.

L’approche alternative à l’isolement d’état d’object consiste à intervertir les méthodes d’access:

 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) 

Utilisez 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