what variable ruby-on-rails ruby ruby-on-rails-3 rspec instance-variables

ruby-on-rails - variable - ruby constants



¿Cómo funcionan las variables de instancia en rspec? (3)

El uso de una variable local en esa instancia significaría que su alcance se restringiría al before y, por lo tanto, daría como resultado un error. El @user es de tipo Usuario pero es una variable de instancia del bloque de describe . Rspec tiene algo de magia que, en tiempo de ejecución, forma una clase de cada bloque de describe . Cada ejemplo (bloque) termina siendo una subclase de dicha clase. La herencia de clase permite a los ejemplos ver @user .

Editado el 2017-05-14

La publicación de blog vinculado ya no está disponible. Actualizando con el enlace de Wayback Machine + alineando la sección relevante aquí.

Tenga en cuenta que esto se considera un anti-patrón como se detalla en esta publicación del blog . Utilice let lugar.

let tiene las siguientes ventajas:

  • Se memoriza cuando se usa varias veces en un ejemplo, pero no en todos los ejemplos.
  • Está cargado de manera perezosa, por lo que no perderá tiempo inicializando la variable para los ejemplos que no hacen referencia a ella.
  • Se generará una excepción si tiene un error tipográfico en el nombre de su variable.

Aquí hay un poco de código del tutorial Ruby on Rails de M Hartl. ¿Alguien puede explicar por qué es necesaria una variable de instancia (@user) y por qué no usar una variable local? Además, dado que se supone que las variables de instancia son las variables en la instancia de una clase, ¿de qué clase se crea una instancia de @user?

require ''spec_helper'' describe User do before { @user = User.new(name: "Example User", email: "[email protected]") } subject { @user } it { should respond_to(:name) } it { should respond_to(:email) } end


No puede usar una variable local porque una variable local existe solo en el alcance del método local. before , subject y genera diferentes ámbitos dentro de la misma clase.

El siguiente codigo

before { user = User.new(name: "Example User", email: "[email protected]") }

elevará una variable indefinida cuando la llames

subject { user }

La instancia @user es una instancia de la clase User (después de todo, la creas con User.new ).

Sin embargo, en lugar de variables de instancia, es posible que desee utilizar el comando let . Además, si lo define

subject { User.new(name: "Example User", email: "[email protected]") }

El uso de before no es obligatorio. También obtendrá el beneficio adicional de obtener un método de subject disponible para acceder a la instancia, igual a definir let(:subject) .


subject anuncios de subject it bloquea están bajo diferentes ámbitos, por lo que las variables locales no funcionarán. @user pertenece a la clase generada por RSpec bajo el capó.