Làm cách nào để sử dụng RS_ecise_raise với bất kỳ loại ngoại lệ nào?


211

Tôi muốn làm một cái gì đó như thế này:

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

Làm thế nào tôi nên làm điều này?

some_method.should_raise exception

... không hoạt động.

Câu trả lời:


380
expect { some_method }.to raise_error

Cú pháp RSpec 1:

lambda { some_method }.should raise_error

Xem tài liệu (đối với cú pháp RSpec 1) và tài liệu RSpec 2 để biết thêm.


5
ahh .. tôi chỉ nhận thấy các dấu ngoặc nhọn!
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
...

Lưu ý: raise_errorraise_exceptioncó thể hoán đổi cho nhau.

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

Lưu ý: raise_errorlà một bí danh cho raise_exception.

Tài liệu: https://www.relishapp.com/rspec

RSpec 2:

RSpec 1:


Đó là một câu trả lời tuyệt vời.
Ziggy

grow_error (/ oops /) là một cách tuyệt vời để kiểm tra chuỗi con trong thông báo ngoại lệ
Serge Seletskyy

1
Cảm ơn bạn đã chỉ ra rằng grow_error và for_exception có thể hoán đổi cho nhau (y)
Yo Ludke

85

Thay vì lambda, hãy sử dụng mong đợi:

   expect { some_method }.to raise_error

Điều này được áp dụng cho các phiên bản gần đây hơn của rspec, tức là rspec 2.0 trở lên.

Xem doco để biết thêm.


Tôi sẽ không sử dụng cái này cho Rspec 1 nhưng với Rspec 2 thì nó hoạt động như bình thường.
ericraio

6
Trên thực tế, theo liên kết tài liệu ở trên, điều này sẽ được mong đợi {some_method} .to grow_error
Guilherme Garnier

Cả bình luận của bạn lẫn trang bạn liên kết để giải thích tại sao expecttốt hơn hay tệ hơn lambda.
Kragen Javier Sitaker

1
mong đợi là cho rspec 2.0 và cao hơn. Điều này làm cho tranh luận về cái nào tốt hơn, vì cú pháp lambda không còn hoạt động nữa
Rob

Điều này không hiệu quả với tôi ở capybara:expect { visit welcome_path }.to raise_error
nnyby

65

Cú pháp đã thay đổi gần đây và bây giờ là:

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

4

Từ phiên bản 3.3 trên rspec-expectionsđá quý sẽ đưa ra cảnh báo cho một grow_error trống mà không có tham số

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

Điều này cung cấp cho bạn một gợi ý rằng mã của bạn có thể thất bại với một lỗi khác với thử nghiệm dự định kiểm tra.

CẢNH BÁO: Sử dụng công cụ đối sánh raise_errormà không cung cấp một lỗi cụ thể hoặc thông báo có nguy cơ sai, vì raise_errorsẽ khớp khi Ruby tăng NoMethodError, NameErrorhoặc ArgumentError, có khả năng cho phép kỳ vọng vượt qua mà không thực hiện phương thức bạn định gọi. Thay vào đó hãy xem xét việc cung cấp một lớp lỗi hoặc thông báo cụ thể. Thông báo này có thể được nén bằng cách cài đặt : RSpec::Expectations.configuration.warn_about_potential_false_positives = false.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.