Today it is quite common to write applications that depend on third-party APIs, or even internal APIs, in this modularized digital world. But it makes testing tricky because dependency has an impact during the testing process:

Test cases will be slow

Test cases might fail if the third-party service is down

Test cases will consume resources in the external service (allowed rate limits)

Sensitive information must be available to make them work (API Keys, secrets, etc)

That’s enough reasons to think of better ways to improve the process, and this is where HTTPretty comes to the rescue.

HTTPretty

HTTPretty is just a mocking library for HTTP requests. Quoting their original words:

Once upon a time a python developer wanted to use a RESTful api, everything was fine but until the day he needed to test the code that hits the RESTful API: what if the API server is down? What if its content has changed?

Lucky for us HTTPretty has a really simple interface and since it monkey patches Python’s socket module, it works independently of the HTTP library used.

Example usage

Lets start with a simple example, let’s mock a 200 response (we will be using the requests library for its simplicity):

import requests import httpretty # First enable HTTPretty (will monkey patch the socket module) httpretty . enable () # Register an URI to patch httpretty . register_uri ( httpretty . GET , 'http://example.com/' , status = 200 ) response = request . get ( 'http://example.com/' ) print ( response . status_code ) # Outputs: 200 print ( response . content ) # Outputs: HTTPretty :) # Remove the patches httpretty . disable ()

We can override the response content of course:

import requests import httpretty httpretty . enable () httpretty . register_uri ( httpretty . GET , 'http://example.com/' , body = 'Overriding the response body' , status = 200 ) response = request . get ( 'http://example.com/' ) print ( response . status_code ) # Outputs: 200 print ( response . content ) # Outputs: Overriding the response body httpretty . disable ()

We can make the response content to be of any type, JSON for example:

import json import requests import httpretty httpretty . enable () json_body = json . dumps ({ 'status' : 'ok' , 'value' : '123' }) httpretty . register_uri ( httpretty . GET , 'http://example.com/' , body = json_body , content_type = 'application/json' , status = 200 ) response = request . get ( 'http://example.com/' ) print ( response . status_code ) # Outputs: 200 print ( response . content ) # Outputs: '{"status": "ok", "value": "123"}' print ( response . json ()) # Outputs: {u'status': u'ok', u'value': u'123'} httpretty . disable ()

For simplicity, there’s a decorator that will call enable() and disable() for us:

import requests import httpretty @ httpretty . activate def test (): httpretty . register_uri ( httpretty . GET , 'http://example.com' , status = 200 , body = 'Testing decorator' ) return requests . get ( 'http://example.com' ) response = test () print ( response . status_code ) # Outputs: 200 print ( response . content ) # Outputs: Testing decorator print ( httpretty . is_enabled ()) # Outputs: False

HTTPretty also support the many HTTP methods beside GET , they can be accessed at:

httpretty.DELETE

httpretty.PUT

httpretty.GET

httpretty.OPTIONS

httpretty.HEAD

httpretty.PATCH

httpretty.POST

Other features are:

Add custom headers with the adding_headers parameter.

parameter. Define multiple response values with the responses parameter, the responses will be returned in order they are defined.

parameter, the responses will be returned in order they are defined. Set a function as body parameter.

parameter. The URI can be defined as a regular expression.

Conclusion

HTTPretty is great tool that helps to speed up the test cases that depend on external APIs. It also help to ensure that the application logic is well defined with the expected responses from the services, and if the third-party changes, it’s not a fault in your code.