tests spectroscopy run rails how example describe rspec

spectroscopy - Como probar pone en rspec



rspec example (5)

Lo que quiero hacer es ejecutar ruby sayhello.rb en la línea de comandos, luego recibir Hello from Rspec .

Lo tengo con esto:

class Hello def speak puts ''Hello from RSpec'' end end hi = Hello.new #brings my object into existence hi.speak

Ahora quiero escribir una prueba en rspec para verificar que la salida de la línea de comandos sea en realidad "Hola de RSpec" y no "Me gusta Unix"

NO FUNCIONA. Actualmente tengo esto en mi archivo sayhello_spec.rb

require_relative ''sayhello.rb'' #points to file so I can ''see'' it describe "sayhello.rb" do it "should say ''Hello from Rspec'' when ran" do STDOUT.should_receive(:puts).with(''Hello from RSpec'') end end

Además, necesito ver cómo se ve la prueba en mi RSPEC, por favor.


Algo similar a la respuesta de bswinnerton, uno puede capturar salidas de prueba y luego compararlas con la salida capturada, sin tener que usar el método de capture dependiente de la biblioteca (que alguien mencionó está en desuso en Rails 5).

Ruby tiene una variable global llamada $stdout que, de forma predeterminada, se rellena con la constante STDOUT . STDOUT es la que envía datos a la secuencia de salida estándar del proceso ruby ​​(no estoy seguro de que "secuencia" sea el término correcto aquí). Básicamente, en un caso ingenuo, STDOUT.puts("foo") hará que aparezca "foo / n" en la ventana de su terminal. $stdout.puts("foo") hará lo mismo porque el nombre de la variable $stdout se refiere a STDOUT menos que lo reasigne (punto clave aquí). Finalmente, puts("foo") es azúcar sintáctica para $stdout.puts("foo") .

La estrategia entonces es reasignar $stdout a una instancia de IO local que pueda inspeccionar después de ejecutar su código, para ver si "Hello from RSpec" apareció en su contenido.

Cómo funcionaría esto:

describe "sayhello.rb" do it "should say ''Hello from Rspec'' when ran" do $stdout = StringIO.new # run the code # (a little funky; would prefer Hello.new.speak here but only changing one thing at a time) require_relative ''sayhello.rb'' $stdout.rewind # IOs act like a tape so we gotta rewind before we play it back expect($stdout.gets.strip).to eq(''Hello from Rspec'') end end


Creo que la mejor manera es usar rspec build in output matcher https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/output-matcher

Por ejemplo, esta es tu clase.

class MakeIt def awesome(text) puts "Awesome #{text}" end end

y tu prueba

describe MakeIt do describe ''#awesome'' do it ''prints awesome things'' do expect do MakeIt.new.awesome(''tests'') end.to output(''Awesome tests'').to_stdout end it ''does not print not awesome things'' do expect do MakeIt.new.awesome(''tests'') end.to_not output(''Not awesome tests'').to_stdout end end end

Agradable, limpio y por el libro!


Está ejecutando su código antes de ingresar al bloque de prueba, por lo que no se cumplen las expectativas. Debe ejecutar el código dentro del bloque de prueba después de establecer las expectativas (por ejemplo, moviendo la declaración require_relative después de la instrucción STDOUT.... ), de la siguiente manera:

describe "sayhello.rb" do it "should say ''Hello from Rspec'' when ran" do STDOUT.should_receive(:puts).with(''Hello from RSpec'') require_relative ''sayhello.rb'' #load/run the file end end


Puedes resolver esto usando la biblioteca active_support Rails, que agrega un método de capture :

require ''active_support/core_ext/kernel/reporting'' require_relative ''sayhello'' describe Hello do it "says ''Hello from RSpec'' when ran" do output = capture(:stdout) do hi = Hello.new hi.speak end expect(output).to include ''Hello from RSpec'' end end


Según las respuestas / comentarios anteriores, una solución que use la nueva sintaxis sin una gema se vería así:

describe "sayhello.rb" do it "should say ''Hello from Rspec'' when run" do expect(STDOUT).to receive(:puts).with(''Hello from RSpec'') require_relative ''sayhello.rb'' # load/run the file end end