2012-01-27 10 views
41

Dada una clase con un par de variables de instancia y algunos métodos. Algunas variables de instancia se configuran como accesibles a través de attr_reader y attr_accessor. Por lo tanto, los otros son privados.
Algunas de las variables de instancia privadas se configuran en uno de los métodos de instancia y se leen/utilizan en otro método.¿Cómo establecer la variable de instancia privada utilizada en una prueba de método?

Para probar Estoy utilizando RSpec. Como todavía soy nuevo para Ruby y quiero hacer las cosas bien, definí que mis pruebas son bastante precisas. Por lo tanto, tengo un bloque describe para cada método de instancia, que a su vez están divididos en un subconjunto de context sy it s. Las condiciones previas ambientales generales se definen con before.

Sin embargo, al probar uno de los métodos, que utiliza pero no establece una de las variables privadas, necesito llamar al otro método, que está configurando esta variable. Esto parece bastante pesado y no modular para mí.

Hay una manera de forzar una variable de instancia privada a un cierto valor. Similar a "arrancando" el valor de una variable de instancia privada con Object::instance_eval(:var).

Respuesta

78

Como se ha contestado en su pregunta de la manera más sencilla de configurar variable de instancia es con instance_eval método:

obj.instance_eval('@a = 1') 

Otra forma es utilizar instance_variable_set:

obj.instance_variable_set(:@a, 1) 

Pero no recomendaría hacer esto yo n tus especificaciones Las especificaciones tratan sobre el comportamiento de prueba de un objeto y el comportamiento de prueba rompiendo la encapsulación de clase con instance_eval hará que sus pruebas sean más frágiles y dependan de la implementación.

enfoque alternativo para oponerse aislamiento estado es a stub métodos de acceso:

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) 
+0

No he pensado aún en los accesos de troquelado. Probablemente, muchos de mis datos de prueba (algunos archivos de texto, que deberían ser detectados y analizados por mi programa) quedarán obsoletos. Parece una buena manera. Gracias :) –

+0

Solo para aclarar, en su respuesta, ¿usted afirma que 'instancia_eval' rompe la encapsulación de clase o que' instancia_variable_set' también lo hace? – Seanny123

+0

@ Seanny123 Tanto 'instance_eval' como' instance_variable_set' modifican el estado interno que es privado para la instancia y no debe modificarse fuera del objeto. –

7

Uso 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 
+0

Gracias de para eso. Sabía que es fácil. :) –

Cuestiones relacionadas