I have a retry block
The primary syntax provided by rspec-expectations is based on the expect method, which explicitly wraps an object or block of code in order to set an expectation on it. There's also an older should-based syntax, which relies upon should being monkey-patched onto every object in the system.
where
fetch_and_rescan_app_instances
access the network so can throw an exception.I want to write an rspec test that it throws an exception first time and doesn't throw an exception second time it gets called, so I can test if the second time it doesn't throw an exception, the my_method won't throw an exeption.
I know i can do
stub(:fetch_and_rescan_app_instances).and_return(1,3)
and first time it returns 1 and second time 3, but I don't know how to do throw an exception first time and return something second time.MatildaMatilda
3 Answers
You can calculate the return value in a block:
Note that you should really not be rescuing from
Exception
, use something more specific. See: Why is it a bad style to `rescue Exception => e` in Ruby?Community♦
Chris Salzberg![Rspec Allow Raise_error Rspec Allow Raise_error](/uploads/1/2/5/6/125681106/387026810.jpg)
24.1k44 gold badges6060 silver badges7070 bronze badges
What you do is constrain the times the message should be received (receive counts), i.e. in your case you can
Calling
instance.fetch_and_rescan_app_instances
first time will raise RuntimeError, and second time will return 'some return value'.PS. Calling more than that will result in an error, you might consider using different receive count specification https://www.relishapp.com/rspec/rspec-mocks/docs/message-expectations/receive-counts
dolzenkodolzenko4,97944 gold badges3232 silver badges2525 bronze badges
This has changed a little in RSpec3.x. It seems the best approach is to pass a block to the
receive
that defines this type of behaviour.The following is from the docs suggesting how to create this type of transit failure:
(This errors every other time it is called... But is easy to adapt.)
xmjwxmjw