Come utilizzare should_raise di RSpec con qualsiasi tipo di eccezione?


211

Mi piacerebbe fare qualcosa del genere:

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

Come dovrei farlo?

some_method.should_raise exception

... non funziona.

Risposte:



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_errore raise_exceptionsono intercambiabili.

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_errorè un alias per raise_exception.

Documentazione: https://www.relishapp.com/rspec

RSpec 2:

RSpec 1:


Questa è stata un'ottima risposta.
Ziggy

raise_error (/ oops /) è un ottimo modo per controllare la sottostringa nel messaggio di eccezione
Serge Seletskyy

1
Grazie per aver sottolineato che raise_error e raise_exception sono intercambiabili (y)
Yo Ludke

85

Invece di lambda, usa aspettati di:

   expect { some_method }.to raise_error

Questo vale per le versioni più recenti di rspec, cioè rspec 2.0 e superiori.

Vedere il documento per ulteriori informazioni.


Non lo userei per Rspec 1 ma per Rspec 2 funziona proprio come dovrebbe.
ericraio

6
In realtà, secondo il link della documentazione sopra, questo dovrebbe essere previsto {some_method} .to raise_error
Guilherme Garnier

Né il tuo commento né la pagina a cui ti colleghi spiegano perché expectè meglio o peggio di lambda.
Kragen Javier Sitaker

1
l'aspettativa è per rspec 2.0 e versioni successive. Ciò rende discutibile l'argomento su quale sia il migliore, poiché la sintassi lambda non funziona più
Rob

Questo non funziona per me in capibara:expect { visit welcome_path }.to raise_error
nnyby

65

La sintassi è cambiata di recente e ora è:

expect { ... }.to raise_error(ErrorClass)

4

Dalla versione 3.3 in poi rspec-expectionsgem solleva un avviso per un raise_error vuoto senza un parametro

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

Questo ti dà un suggerimento che il tuo codice potrebbe non riuscire con un errore diverso da quello che il test intendeva controllare.

ATTENZIONE: Usare il raise_errormatcher senza fornire un errore o un messaggio specifico rischia di falsi positivi, poiché raise_errorcorrisponderà quando Ruby solleva un NoMethodError, NameErroro ArgumentError, potenzialmente permettendo che l'aspettativa passi senza nemmeno eseguire il metodo che si intende chiamare. Considerare invece di fornire una classe o un messaggio di errore specifico. Questo messaggio può essere soppressa per impostazione: RSpec::Expectations.configuration.warn_about_potential_false_positives = false.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.