Creating Responses¶
Note
The examples within use this syntax because response creation is a function of the adapter and not the mocker. All the same arguments can be provided to the mocker if that is how you use requests_mock within your project, and use the
mock.get(url, ...)
form in place of the given:
adapter.register_uri('GET', url, ...)
If you are not familiar with requests’ adapters (see Adapter Usage), prefer the mocker approach (see Using the Mocker).
Registering Responses¶
Responses are registered with the requests_mock.Adapter.register_uri()
function on the adapter.
>>> adapter.register_uri('GET', 'mock://test.com', text='Success')
>>> resp = session.get('mock://test.com')
>>> resp.text
'Success'
register_uri()
takes the HTTP method, the URI and then information that is used to build the response. This information includes:
- status_code:
The HTTP status response to return. Defaults to 200.
- reason:
The reason text that accompanies the Status (e.g. ‘OK’ in ‘200 OK’)
- headers:
A dictionary of headers to be included in the response.
- cookies:
A CookieJar containing all the cookies to add to the response.
To specify the body of the response there are a number of options that depend on the format that you wish to return.
- json:
A python object that will be converted to a JSON string.
- text:
A unicode string. This is typically what you will want to use for regular textual content.
- content:
A byte string. This should be used for including binary data in responses.
- body:
A file like object that contains a .read() function.
- raw:
A prepopulated
urllib3.response.HTTPResponse
to be returned.- exc:
An exception that will be raised instead of returning a response.
These options are named to coincide with the parameters on a requests.Response
object. For example:
>>> adapter.register_uri('GET', 'mock://test.com/1', json={'a': 'b'}, status_code=200)
>>> resp = session.get('mock://test.com/1')
>>> resp.json()
{'a': 'b'}
>>> adapter.register_uri('GET', 'mock://test.com/2', text='Not Found', status_code=404)
>>> resp = session.get('mock://test.com/2')
>>> resp.text
'Not Found'
>>> resp.status_code
404
It only makes sense to provide at most one body element per response.
Dynamic Response¶
A callback can be provided in place of any of the body elements. Callbacks must be a function in the form of
def callback(request, context):
and return a value suitable to the body element that was specified. The elements provided are:
- request:
The
requests.Request
object that was provided.- context:
An object containing the collected known data about this response.
The available properties on the context are:
- headers:
The dictionary of headers that are to be returned in the response.
- status_code:
The status code that is to be returned in the response.
- reason:
The string HTTP status code reason that is to be returned in the response.
- cookies:
A
requests_mock.CookieJar
of cookies that will be merged into the response.
These parameters are populated initially from the variables provided to the register_uri()
function and if they are modified on the context object then those changes will be reflected in the response.
>>> def text_callback(request, context):
... context.status_code = 200
... context.headers['Test1'] = 'value1'
... return 'response'
...
>>> adapter.register_uri('GET',
... 'mock://test.com/3',
... text=text_callback,
... headers={'Test2': 'value2'},
... status_code=400)
>>> resp = session.get('mock://test.com/3')
>>> resp.status_code, resp.headers, resp.text
(200, {'Test1': 'value1', 'Test2': 'value2'}, 'response')
Response Lists¶
Multiple responses can be provided to be returned in order by specifying the keyword parameters in a list. If the list is exhausted then the last response will continue to be returned.
>>> adapter.register_uri('GET', 'mock://test.com/4', [{'text': 'resp1', 'status_code': 300},
... {'text': 'resp2', 'status_code': 200}])
>>> resp = session.get('mock://test.com/4')
>>> (resp.status_code, resp.text)
(300, 'resp1')
>>> resp = session.get('mock://test.com/4')
>>> (resp.status_code, resp.text)
(200, 'resp2')
>>> resp = session.get('mock://test.com/4')
>>> (resp.status_code, resp.text)
(200, 'resp2')
Callbacks work within response lists in exactly the same way they do normally;
>>> adapter.register_uri('GET', 'mock://test.com/5', [{'text': text_callback}]),
>>> resp = session.get('mock://test.com/5')
>>> resp.status_code, resp.headers, resp.text
(200, {'Test1': 'value1', 'Test2': 'value2'}, 'response')
Raising Exceptions¶
When trying to emulate a connection timeout or SSLError you need to be able to throw an exception when a mock is hit. This can be achieved by passing the exc parameter instead of a body parameter.
>>> adapter.register_uri('GET', 'mock://test.com/6', exc=requests.exceptions.ConnectTimeout),
>>> session.get('mock://test.com/6')
Traceback (most recent call last):
...
ConnectTimeout: