Jak korzystać z RS_Pec'u should_raise z jakimkolwiek wyjątkiem?

211

Chciałbym zrobić coś takiego:

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

Jak mam to zrobić?

some_method.should_raise exception

... nie działa.

marcgg
źródło

Odpowiedzi:

380
expect { some_method }.to raise_error

Składnia RSpec 1:

lambda { some_method }.should raise_error

Zobacz dokumentację (składnia RSpec 1) i dokumentację RSpec 2, aby uzyskać więcej.

Avdi
źródło
5
ahh .. Właśnie zauważyłem kręcone szelki!
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
...

Uwaga: raise_errori raise_exceptionsą wymienne.

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
...

Uwaga: raise_errorto alias dla raise_exception.

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

RSpec 2:

RSpec 1:

joelparkerhenderson
źródło
To była świetna odpowiedź.
Ziggy
raise_error (/ oops /) to świetny sposób na sprawdzenie podłańcucha w komunikacie wyjątku
Serge Seletskyy
1
Dzięki za zwrócenie uwagi na to, że podwyższenie błędu i wyjątek podwyżki są wymienne (y)
Yo Ludke,
85

Zamiast lambda użyj, aby:

   expect { some_method }.to raise_error

Dotyczy to nowszych wersji rspec, tj. Rspec 2.0 i nowszych.

Zobacz dokumentację, aby uzyskać więcej.

racc
źródło
Nie użyłbym tego dla Rspec 1, ale dla Rspec 2 działa tak, jak powinien.
ericraio
6
Właściwie, zgodnie z powyższym linkiem do dokumentacji, należy się spodziewać {some_method} .to raise_error
Guilherme Garnier
Ani Twój komentarz, ani strona, do której prowadzą linki, nie wyjaśniają, dlaczego expectjest lepszy czy gorszy niż lambda.
Kragen Javier Sitaker
1
Oczekiwany jest dla rspec 2.0 i nowszych. To sprawia, że ​​dyskusja na temat tego, który z nich jest lepszy, jest niemożliwa, ponieważ składnia lambda już nie działa
Rob
To nie działa dla mnie w expect { visit welcome_path }.to raise_error
Kapibara
65

Składnia zmieniła się ostatnio i teraz jest:

expect { ... }.to raise_error(ErrorClass)
ayckoster
źródło
4

Od wersji 3.3 na rspec-expectionsklejnotach pojawia się ostrzeżenie o pustej podwyżce_błędu bez parametru

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

Daje to podpowiedź, że Twój kod może zawieść z innym błędem niż test przeznaczony do sprawdzenia.

OSTRZEŻENIE: Używanie modułu raise_errordopasowywania bez podania konkretnego błędu lub komunikatu grozi fałszywymi raise_errortrafieniami , ponieważ będzie pasować, gdy Ruby podniesie wartość NoMethodError, NameErrorlub ArgumentError, potencjalnie umożliwiając oczekiwanie, nawet bez wykonania metody, którą zamierzasz wywołać. Zamiast tego rozważ podanie konkretnej klasy błędu lub komunikatu. Komunikat ten może być stłumiony przez ustawienie: RSpec::Expectations.configuration.warn_about_potential_false_positives = false.

Bruno E.
źródło