问题
I am trying to simulate unexpected behaviour from a web api, such as not finding the server and timeouts, using webmock.
What would be the best way to do this? All I can think of is to do something like this:
stubbed_request = stub_request(:get, "#{host}/api/something.json").
with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}).
to_return(:status => [500, "Internal Server Error"])
That should work for things like 404 etc., but how can I test timeouts, server not found/offline server, and no internet connection?
回答1:
After some digging I found some solutions to this.
Apparently you can change the to_return(...)
to to_timeout
, which will throw a timeout error. You can also have to_raise(StandardError)
. For full reference, see https://github.com/bblimke/webmock#raising-timeout-errors.
Timeout, or server not found, example:
stubbed_request = stub_request(:get, "#{host}/api/something.json").
with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}).
to_timeout
Raise StandardError, or no internet/other exception, example:
stubbed_request = stub_request(:get, "#{host}/api/something.json").
with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}).
to_raise(StandardError)
#Error example 2:
stubbed_request = stub_request(:get, "#{host}/api/something.json").
with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}).
to_raise("My special error")
There you go, not too hard after all.
I have no idea how I didn't find this the first time. Anyway, hope this helps someone out one day.
回答2:
Came across this question and decided to add supportive materials. According to a discussion in WebMock issue (https://github.com/bblimke/webmock/issues/16), the timeout can be simulated in two ways.
The first way is two use .to_raise(e):
stubbed_request = stub_request(:get, "#{host}/api/something.json").
with(:headers => {'Accept'=>'*/*', 'Content-Type'=>'application/json', 'User-
Agent'=>'Ruby'}).to_raise(e)
Where e is a library specific timeout exception. quotation: "The whole point of WebMock is to be HTTP client library independent so to_timeout should work with every library. The problem is that different libraries return different errors, ie Net::HTTP return Ruby Timeout::Error while HTTPClient raises HTTPClient:: TimeoutError. This behavior can be replicated in WebMock but the error handling code will have to be different any time you change the library."
The second way is to use the following sample:
stub_request(:any, 'www.example.net').to_timeout
RestClient.post('www.example.net', 'abc') # ===> RestClient::RequestTimeout
Here is the original source: https://github.com/bblimke/webmock/issues/16
来源:https://stackoverflow.com/questions/25552239/webmock-simulate-failing-api-no-internet-timeout