Entendí la diferencia entre let
y let!
con un ejemplo muy simple. Permítame leer la oración del documento primero, luego mostrar la salida de manos.
About let doc dice: -
... let
es -perezoso evaluado: no se evalúa hasta la primera vez el método que se invoca define.
entendí la diferencia con el siguiente ejemplo: -
$count = 0
describe "let" do
let(:count) { $count += 1 }
it "returns 1" do
expect($count).to eq(1)
end
end
que le permite correr ahora: -
[email protected]:~/Ruby> rspec spec/test_spec.rb
F
Failures:
1) let is not cached across examples
Failure/Error: expect($count).to eq(1)
expected: 1
got: 0
(compared using ==)
# ./spec/test_spec.rb:8:in `block (2 levels) in <top (required)>'
Finished in 0.00138 seconds (files took 0.13618 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/test_spec.rb:7 # let is not cached across examples
[email protected]:~/Ruby>
Por qué la ERROR? Porque, como dice el documento, con let
, , no se evalúa hasta la primera vez que se invoca el método que define. En el ejemplo, no hemos invocado el count
, por lo tanto $count
sigue siendo 0
, no se ha incrementado en 1
.
Ahora viene a la parte let!
. El doc dice
.... Puedes usar let! forzar la invocación del método antes de cada ejemplo. Esto significa que incluso si no invocó el helper método dentro del ejemplo, aún se invocará antes de ejecutar su ejemplo.
Permite probar esto también: -
Este es el código modificado
$count = 0
describe "let" do
let!(:count) { $count += 1 }
it "returns 1" do
expect($count).to eq(1)
end
end
Permite ejecutar este código: -
[email protected]:~/Ruby> rspec spec/test_spec.rb
.
Finished in 0.00145 seconds (files took 0.13458 seconds to load)
1 example, 0 failures
Sede, ahora $count
vuelve 1
, por lo tanto la prueba ha pasado. Sucedió cuando usé let!
, que se ejecuta antes de la ejecución de ejemplo, aunque no invocamos count
dentro de nuestro ejemplo.
Así es como let
y let!
se diferencian entre sí.
De acuerdo, por lo que la primera especificación tiene sentido. Seguramente, sin embargo, la segunda especificación se evaluaría antes del ejemplo, (haciéndolo igual a 1) y luego otra vez cuando se llama al "conteo.debería" (haciéndolo igual a 2). –
No, ya se invoca y se memoriza, por lo que el recuento de $ no vuelve a aumentar. De todos modos, si tiene otro ejemplo, se vuelve a invocar el enlace anterior. Ver mi respuesta editada, agregué un código para aclararme. – dhoelzgen
Eso significa que si usa "let" y una especificación (un "it") no hace "count".debería "(o similar) entonces el incremento no tendrá lugar? Si ese es el caso, entonces" let "no debería considerarse un" antes ", ya que antes de forma predeterminada implica la funcionalidad de" let! ". O ¿Me estoy perdiendo algo de nuevo? –