¿Cómo usar RSpec's should_raise con algún tipo de excepción?

211

Me gustaría hacer algo como esto:

some_method.should_raise <any kind of exception, I don't care>

¿Cómo debería hacer esto?

some_method.should_raise exception

... no funciona

marcgg
fuente

Respuestas:

380
expect { some_method }.to raise_error

Sintaxis de RSpec 1:

lambda { some_method }.should raise_error

Consulte la documentación (para la sintaxis de RSpec 1) y la documentación de RSpec 2 para obtener más información.

Avdi
fuente
55
ahh .. ¡Acabo de notar las llaves!
Louis Sayers
88

RSpec 2

expect { some_method }.to raise_error
expect { some_method }.to raise_error(SomeError)
expect { some_method }.to raise_error("oops")
expect { some_method }.to raise_error(/oops/)
expect { some_method }.to raise_error(SomeError, "oops")
expect { some_method }.to raise_error(SomeError, /oops/)
expect { some_method }.to raise_error(...){|e| expect(e.data).to eq "oops" }

# Rspec also offers to_not:
expect { some_method }.to_not raise_error
...

Nota: raise_errory raise_exceptionson intercambiables.

RSpec 1

lambda { some_method }.should raise_error
lambda { some_method }.should raise_error(SomeError)
lambda { some_method }.should raise_error(SomeError, "oops")
lambda { some_method }.should raise_error(SomeError, /oops/)
lambda { some_method }.should raise_error(...){|e| e.data.should == "oops" }

# Rspec also offers should_not:
lambda { some_method }.should_not raise_error
...

Nota: raise_errores un alias para raise_exception.

Documentación: https://www.relishapp.com/rspec

RSpec 2:

RSpec 1:

joelparkerhenderson
fuente
Esa fue una gran respuesta.
Ziggy
raise_error (/ oops /) es una excelente manera de verificar la subcadena en el mensaje de excepción
Serge Seletskyy
1
Gracias por señalar que raise_error y raise_exception son intercambiables (y)
Yo Ludke
85

En lugar de lambda, use esperar para:

   expect { some_method }.to raise_error

Esto se aplica a las versiones más recientes de rspec, es decir, rspec 2.0 y versiones posteriores.

Ver el doco para más.

racc
fuente
No usaría esto para Rspec 1, pero para Rspec 2 funciona como debería.
ericraio
66
En realidad, de acuerdo con el enlace de documentación anterior, esto debería esperarse {some_method} .to raise_error
Guilherme Garnier
Ni su comentario ni la página a la que enlaza explican por qué expectes mejor o peor que lambda.
Kragen Javier Sitaker
1
esperar es para rspec 2.0 y superior. Esto hace discutible el argumento sobre cuál es mejor, ya que la sintaxis lambda ya no funciona
Rob
Esto no me funciona en el carpincho:expect { visit welcome_path }.to raise_error
nnyby
65

La sintaxis cambió recientemente y ahora es:

expect { ... }.to raise_error(ErrorClass)
ayckoster
fuente
4

A partir de la versión 3.3 en rspec-expectionsgem, se genera una advertencia para un raise_error en blanco sin un parámetro

expect { raise StandardError }.to raise_error # results in warning
expect { raise StandardError }.to raise_error(StandardError) # fine

Esto le da una pista de que su código puede fallar con un error diferente al de la prueba que se pretende verificar.

ADVERTENCIA: El uso raise_errorde coincidencias sin proporcionar un mensaje de error o riesgos específicos de los falsos positivos, ya que raise_errorcoincidirá cuando Rubí plantea una NoMethodError, NameErroro ArgumentError, lo que permitiría la expectativa de pasar sin ni siquiera ejecutar el método se viene a llamar. En su lugar, considere proporcionar una clase o mensaje de error específico. Este mensaje puede ser suprimida por el ajuste: RSpec::Expectations.configuration.warn_about_potential_false_positives = false.

Bruno E.
fuente