supresion resueltos parentesis operaciones matematicos llaves fracciones eliminar ejercicios corchetes con como combinadas ruby rspec

ruby - resueltos - operaciones con parentesis corchetes y llaves



¿Cuándo usar llaves entre paréntesis y paréntesis en el método Rspec esperado? (4)

En la prueba escrita entre paréntesis, el código se ejecuta normalmente, incluido todo el manejo normal de errores. La sintaxis de rizado define un objeto de bloque en el que puede colocar la expectativa. Encapsula el código que espera que se rompa y permite que rspec detecte el error y proporcione su propio manejo (en este caso, una prueba exitosa).

También puede pensarlo de esta manera: con los paréntesis, el código se ejecuta antes de pasar al método de expect , pero con el bloque, expect ejecutará el código en sí.

Tuve una prueba que hizo esto:

expect(@parser.parse(''adsadasdas'')).to raise_error(Errno::ENOENT)

y no funcionó. Me cambié a

expect { @parser.parse(''adsadasdas'') }.to raise_error(Errno::ENOENT)

Y funcionó.

¿Cuándo usamos llaves y cuándo usamos paréntesis con expectativa?


En respuesta al comentario de OP, he editado y reescrito completamente mi respuesta. Me doy cuenta de que mi respuesta original fue simplificada en exceso, tanto que podría considerarse incorrecta.

Su pregunta fue abordada de alguna manera por esta otra pregunta de .

Un cartel, Peter Alfvin , hace un buen punto cuando dice:

En cuanto a las reglas, pasa un bloque o un Proc si está tratando de probar el comportamiento (por ejemplo, aumentar errores, cambiar algún valor). De lo contrario, pasa un argumento "convencional", en cuyo caso el valor de ese argumento es lo que se prueba.

La razón por la que te encuentras con el fenómeno que estás viendo tiene que ver con el aumento de errores. Cuando pasas @parser.parse(''adsadasdas'') como argumento (usa paréntesis) para expect , esencialmente le estás diciendo a ruby:

  1. Evalúa @parser.parse(''adsadasdas'') .
  2. Toma el resultado y pasa esto para expect .
  3. expect debería ver si este resultado coincide con mi expectativa (es decir, que Errno:ENOENT generará).

Pero, lo que sucede es que cuando ruby ​​evalúa @parser.parse(''adsadasdas'') , se @parser.parse(''adsadasdas'') un error en ese momento. Ruby ni siquiera tiene la oportunidad de pasar el resultado para expect . (Para todo lo que nos importa, podría haber pasado @parser.parse(''adsadasdas'') como un argumento a cualquier función ... como multiply() o capitalize() ) El error se genera, y expect nunca tenga la oportunidad de hacer su trabajo

Pero cuando pasas @parser.parse(''adsadasdas'') como un proc (un bloque de código) para expect usando llaves, lo que le estás diciendo a ruby ​​es esto:

  1. expect , prepárate para hacer algún trabajo.
  2. expect , me gustaría que mantuvieran un registro de lo que sucede cuando evaluamos @parser.parse(''adsadasdas'') .
  3. Ok, expect , ¿el bloque de código que se acaba de evaluar Errno:ENOENT un error Errno:ENOENT ? Esperaba que lo hiciera.

Cuando pasa un bloque de código para expect , está diciendo que expect que examine el comportamiento resultante, los cambios realizados por la ejecución de su bloque de código y luego que le avise si cumple con las expectativas que usted le proporcionó. .

Cuando pasa un argumento para expect , le está diciendo a Ruby que evalúe ese argumento para expect tenga algún valor antes de que expect se involucre, y luego está pasando ese valor para expect ver si cumple con alguna expectativa.


TL; DR: use expect(exp) para especificar algo sobre el valor de exp y use expect { exp } para especificar un efecto secundario que se produce cuando se ejecuta exp .

Vamos a desempacar un poco. La mayoría de los emparejadores de RSpec son emparejadores de valor . Coinciden (o no) contra cualquier objeto rubí. En contraste, un puñado de los emparejadores de RSpec solo se pueden emparejar contra un bloque, porque tienen que observar el bloque mientras se está ejecutando para funcionar correctamente. Estos emparejadores se refieren a los efectos secundarios que tienen lugar (o no) mientras se ejecuta el bloque. El emparejador no tendría manera de saber si el efecto secundario mencionado había ocurrido a menos que se le haya pasado un bloque para ejecutar. Consideremos los emparejadores de bloques incorporados (a partir de RSpec 3.1) uno por uno:

raise_error

Tenga en cuenta que uno puede devolver una excepción desde un método, y eso es diferente a elevar la excepción. El aumento de una excepción es un efecto secundario, y solo puede ser observado por el jugador que ejecuta el bloqueo con una cláusula de rescue apropiada. Por lo tanto, este emparejador debe recibir un bloque para que funcione correctamente.

throw_symbol

Lanzar símbolos es similar a generar errores: provoca un salto de pila y es un efecto secundario que solo se puede observar al ejecutar un bloque dentro de un bloque de catch apropiado.

change

La mutación al estado es un efecto secundario. El emparejador solo puede saber si hubo un cambio en algún estado al verificar el estado de antemano, ejecutar el bloque y luego verificar el estado después.

output

I / O es un efecto secundario. Para que el emparejador de output funcione, debe reemplazar la secuencia apropiada ( $stdout o $stderr ) con una nueva StringIO, execute the block, restore the stream to its original value, and then check the contents of the StringIO`.

yield_control / yield_with_args / yield_with_no_args / yield_with_successive_args

Estos matchers son un poco diferentes. El rendimiento no es realmente un efecto secundario (en realidad es solo azúcar sintáctica para llamar a otra función proporcionada por el llamante), pero el rendimiento no se puede observar al observar el valor de retorno de la expresión. Para que los ajustadores de rendimiento funcionen, proporcionan un objeto de probe que pasas al método bajo prueba como un bloque usando la sintaxis de la &probe :

expect { |probe| [1, 2, 3].each(&probe) }.to yield_with_successive_args(1, 2, 3)

¿Qué tienen en común todos estos emparejadores? Ninguno de ellos puede trabajar en valores rubí simples. En su lugar, todos tienen que envolver un bloque en un contexto apropiado (es decir, rescatar, capturar o verificar los valores de antes / después).

Tenga en cuenta que en RSpec 3, agregamos cierta lógica para proporcionar a los usuarios errores claros cuando usan la forma de expect incorrecta con un emparejador determinado. Sin embargo, en el caso específico de expect(do_something).to raise_error , no hay nada que podamos hacer para proporcionarle una explicación clara allí: si do_something genera un error (como espera que ...), se genera el error. antes de que ruby ​​evalúe el argumento to (el raise_error raise_error), RSpec no tiene manera de verificar con el matcher para ver si apoya las expectativas de valor o de bloque.


en breve:

  • use curly-brace (un bloque): cuando quiera probar el behavior
  • use paréntesis cuando quiera probar el returned value

vale la pena leer: en As for rules, you pass a block or a Proc if you''re trying to test behavior (eg raising errors, changing some value). Otherwise, you pass a "conventional" argument, in which case the value of that argument is what is tested. As for rules, you pass a block or a Proc if you''re trying to test behavior (eg raising errors, changing some value). Otherwise, you pass a "conventional" argument, in which case the value of that argument is what is tested. - de esta respuesta