28 votos

¿Cómo puedo validar las salidas y se anula en RSpec?

Estoy tratando de especificación de los comportamientos de argumentos de línea de comandos que mi script recibe para asegurarse de que todos validación pasa. Algunos de mis argumentos de línea de comandos será el resultado en abort o exit invocada debido a que los parámetros proporcionados son incorrectos o incompletos.

Estoy tratando de hacer algo como esto que no funciona:

# something_spec.rb
require 'something'
describe Something do
    before do
        Kernel.stub!(:exit)
    end

    it "should exit cleanly when -h is used" do
        s = Something.new
        Kernel.should_receive(:exit)
        s.process_arguments(["-h"])
    end
end

El exit método de cocción limpia la prevención de RSpec de la validación de la prueba (me sale "SystemExit: exit").

También he intentado mock(Kernel) pero eso es demasiado no funciona como me gustaría (no veo ninguna diferencia discernible, pero eso es probablemente porque no estoy seguro de cómo exactamente para burlarse de Kernel y asegúrese de que el burlaban de Kernel es utilizada en mi Something de la clase).

19voto

Markus Strauss Puntos 737

intente esto:

module MyGem
  describe "CLI" do
    context "execute" do

      it "should exit cleanly when -h is used" do
        argv=["-h"]
        out = StringIO.new
        lambda { ::MyGem::CLI.execute( out, argv) }.should raise_error SystemExit
      end

    end
  end
end

14voto

Greg Puntos 783

Gracias por la respuesta Markus. Una vez tuve esta idea de que yo podría armar un buen comparador para uso futuro.

it "should exit cleanly when -h is used" do
  lambda { ::MyGem::CLI.execute( StringIO.new, ["-h"]) }.should exit_with_code(0)
end
it "should exit with error on unknown option" do
  lambda { ::MyGem::CLI.execute( StringIO.new, ["--bad-option"]) }.should exit_with_code(-1)
end

Para usar este comparador añadir esto a sus bibliotecas o spec-ayudantes:

RSpec::Matchers.define :exit_with_code do |exp_code|
  actual = nil
  match do |block|
    begin
      block.call
    rescue SystemExit => e
      actual = e.status
    end
    actual and actual == exp_code
  end
  failure_message_for_should do |block|
    "expected block to call exit(#{exp_code}) but exit" +
      (actual.nil? ? " not called" : "(#{actual}) was called")
  end
  failure_message_for_should_not do |block|
    "expected block not to call exit(#{exp_code})"
  end
  description do
    "expect block to call exit(#{exp_code})"
  end
end

2voto

Kris Puntos 3781

No es bonito, pero he estado usando esto:

begin
  do_something
rescue SystemExit => e
  expect(e.status).to eq 1 # exited with failure status
  # or
  expect(e.status).to eq 0 # exited with success status
else
  expect(true).eq false # this should never happen
end

1voto

cfeduke Puntos 13153

Después de cavar, me encontré con este.

Mi solución final parecido a esto:

# something.rb
class Something
    def initialize(kernel=Kernel)
        @kernel = kernel
    end

    def process_arguments(args)
        @kernel.exit
    end
end

# something_spec.rb
require 'something'
describe Something do
    before :each do
        @mock_kernel = mock(Kernel)
        @mock_kernel.stub!(:exit)
    end

    it "should exit cleanly" do
        s = Something.new(@mock_kernel)
        @mock_kernel.should_receive(:exit)
        s.process_arguments(["-h"])
    end
end

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X