Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock a HTTP request that times out with HTTPretty

Using the HTTPretty library for Python, I can create mock HTTP responses of choice and then pick them up i.e. with the requests library like so:

import httpretty
import requests

# set up a mock
httpretty.enable()
httpretty.register_uri(
            method=httpretty.GET,
            uri='http://www.fakeurl.com',
            status=200,
            body='My Response Body'
        )

response = requests.get('http://www.fakeurl.com')

# clean up
httpretty.disable()
httpretty.reset()

print(response)

Out: <Response [200]>

Is there also the possibility to register an uri which cannot be reached (e.g. connection timed out, connection refused, ...) such that no response is received at all (which is not the same as an established connection which gives an HTTP error code like 404)?

I want to use this behaviour in unit testing to ensure that my error handling works as expected (which does different things in case of 'no connection established' and 'connection established, bad bad HTTP status code'). As a workaround, I could try to connect to an invalid server like http://192.0.2.0 which would time out in any case. However, I would prefer to do all my unit testing without using any real network connections.

like image 469
Dirk Avatar asked Feb 23 '15 14:02

Dirk


1 Answers

Meanwhile I got it, using a HTTPretty callback body seems to produce the desired behaviour. See inline comments below. This is actually not exactly the same as I was looking for (it is not a server that cannot be reached and hence the request times out but a server that throws a timeout exception once it is reached, however, the effect is the same for my usecase.

Still, if anybody knows a different solution, I'm looking forward to it.

import httpretty
import requests

# enable HTTPretty
httpretty.enable()

# create a callback body that raises an exception when opened
def exceptionCallback(request, uri, headers):

    # raise your favourite exception here, e.g. requests.ConnectionError or requests.Timeout
    raise requests.Timeout('Connection timed out.')

# set up a mock and use the callback function as response's body
httpretty.register_uri(
            method=httpretty.GET,
            uri='http://www.fakeurl.com',
            status=200,
            body=exceptionCallback
        )

# try to get a response from the mock server and catch the exception
try:
    response = requests.get('http://www.fakeurl.com')
except requests.Timeout as e:

    print('requests.Timeout exception got caught...')
    print(e)

    # do whatever...

# clean up
httpretty.disable()
httpretty.reset()
like image 102
Dirk Avatar answered Sep 25 '22 20:09

Dirk