Bagaimana cara menggunakan RSpec's should_raise dengan segala macam pengecualian?

211

Saya ingin melakukan sesuatu seperti ini:

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

Bagaimana saya harus melakukan ini?

some_method.should_raise exception

... tidak bekerja.

marcgg
sumber

Jawaban:

380
expect { some_method }.to raise_error

Sintaks RSpec 1:

lambda { some_method }.should raise_error

Lihat dokumentasi (untuk sintaksis RSpec 1) dan dokumentasi RSpec 2 untuk lebih lanjut.

Avdi
sumber
5
ahh .. Aku baru sadar kurung kurawal!
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
...

Catatan: raise_errordan raise_exceptiondapat dipertukarkan.

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

Catatan: raise_erroradalah alias untuk raise_exception.

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

RSpec 2:

RSpec 1:

joelparkerhenderson
sumber
Itu jawaban yang bagus.
Ziggy
rais_error (/ oops /) adalah cara yang bagus untuk memeriksa substring dalam pesan pengecualian
Serge Seletskyy
1
Terima kasih telah menunjukkan bahwa rais_error dan untuk rais_exception dapat dipertukarkan (y)
Yo Ludke
85

Alih-alih lambda, gunakan harapkan untuk:

   expect { some_method }.to raise_error

Ini berlaku untuk versi rspec yang lebih baru, yaitu rspec 2.0 dan lebih tinggi.

Lihat acara dokumenter untuk lebih.

racc
sumber
Saya tidak akan menggunakan ini untuk Rspec 1 tetapi untuk Rspec 2 berfungsi sebagaimana mestinya.
ericraio
6
Sebenarnya, sesuai dengan tautan dokumentasi di atas, ini seharusnya diharapkan {some_method} .to meningkatkan_error
Guilherme Garnier
Baik komentar maupun halaman yang Anda tautkan menjelaskan mengapa expectlebih baik atau lebih buruk daripada lambda.
Kragen Javier Sitaker
1
harapkan untuk rspec 2.0 dan lebih tinggi. Hal ini membuat memperdebatkan argumen tentang mana yang lebih baik, karena sintaks lambda tidak berfungsi lagi
Rob
Ini tidak berfungsi untuk saya di capybara:expect { visit welcome_path }.to raise_error
nnyby
65

Sintaks berubah baru-baru ini dan sekarang adalah:

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

Dari versi 3.3 on rspec-expectionsgem memunculkan peringatan untuk rais_error kosong tanpa parameter

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

Ini memberi Anda petunjuk bahwa kode Anda mungkin gagal dengan kesalahan yang berbeda dari tes yang dimaksudkan untuk memeriksa.

PERINGATAN: Menggunakan raise_errorpencocokan tanpa memberikan kesalahan spesifik atau pesan berisiko positif palsu, karena raise_errorakan cocok ketika Ruby menaikkan NoMethodError, NameErroratau ArgumentError, berpotensi membiarkan harapan lewat tanpa bahkan menjalankan metode yang ingin Anda panggil. Alih-alih mempertimbangkan untuk memberikan kelas kesalahan atau pesan tertentu. Pesan ini dapat ditekan dengan pengaturan: RSpec::Expectations.configuration.warn_about_potential_false_positives = false.

Bruno E.
sumber