Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebMock simulate failing API (no internet, timeout ++)

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?

like image 629
Automatico Avatar asked Aug 28 '14 15:08

Automatico


2 Answers

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.

like image 55
Automatico Avatar answered Oct 26 '22 14:10

Automatico


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

like image 26
sergey.radov Avatar answered Oct 26 '22 15:10

sergey.radov