How to use RSpec's should_raise with any kind of exception?
Solution 1
expect { some_method }.to raise_error
RSpec 1 Syntax:
lambda { some_method }.should raise_error
See the documentation (for RSpec 1 syntax) and RSpec 2 documentation for more.
Solution 2
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
...
Note: raise_error
and raise_exception
are interchangeable.
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
...
Note: raise_error
is an alias for raise_exception
.
Documentation: https://www.relishapp.com/rspec
RSpec 2:
- https://www.relishapp.com/rspec/rspec-expectations/v/2-13/docs/built-in-matchers/raise-error-matcher
RSpec 1:
- http://apidock.com/rspec/Spec/Matchers/raise_error
- http://apidock.com/rspec/Spec/Matchers/raise_exception
Solution 3
Instead of lambda, use expect to:
expect { some_method }.to raise_error
This is applies for more recent versions of rspec, i.e. rspec 2.0 and up.
See the doco for more.
Solution 4
The syntax changed recently and now it is:
expect { ... }.to raise_error(ErrorClass)
Solution 5
From version 3.3 on rspec-expections
gem raises a warning for a blank raise_error without a parameter
expect { raise StandardError }.to raise_error # results in warning
expect { raise StandardError }.to raise_error(StandardError) # fine
This gives you a hint that your code may fail with a different error than the test intended to check.
WARNING: Using the
raise_error
matcher without providing a specific error or message risks false positives, sinceraise_error
will match when Ruby raises aNoMethodError
,NameError
orArgumentError
, potentially allowing the expectation to pass without even executing the method you are intending to call. Instead consider providing a specific error class or message. This message can be supressed by setting:RSpec::Expectations.configuration.warn_about_potential_false_positives = false
.
Related videos on Youtube
marcgg
Trying to build useful software. Find me on twitter or give my blog a read!
Updated on July 25, 2020Comments
-
marcgg almost 4 years
I'd like to do something like this:
some_method.should_raise <any kind of exception, I don't care>
How should I do this?
some_method.should_raise exception
... doesn't work.
-
ericraio about 12 yearsI wouldn't use this for Rspec 1 but for Rspec 2 it works just as it should.
-
Guilherme Garnier about 12 yearsActually, according with the documentation link above, this should be expect { some_method }.to raise_error
-
Kragen Javier Sitaker about 12 yearsNeither your comment nor the page you link to explains why
expect
is better or worse thanlambda
. -
Rob over 11 yearsexpect is for rspec 2.0 and higher. This renders moot the argument about which one is better, since the lambda syntax doesn't work any more
-
Sergiy Seletskyy over 10 yearsraise_error(/oops/) is a great way to check substring in exception message
-
nnyby over 10 yearsThis doesn't work for me in capybara:
expect { visit welcome_path }.to raise_error
-
Louis Sayers over 10 yearsahh.. I just noticed the curly braces!
-
Yo Ludke over 8 yearsThanks for pointing out that raise_error and for raise_exception are interchangeable (y)