Update docs
Update the docs to reference new features and the more recent way that statements are written. Change-Id: I7fc00143b9ab4366a00324aaf59d59baecf9da4a
This commit is contained in:
123
docs/adapter.rst
123
docs/adapter.rst
@@ -18,127 +18,4 @@ The standard `requests`_ means of using an adapter is to :py:meth:`~requests.Ses
|
|||||||
|
|
||||||
At this point any requests made by the session to a URI starting with `mock://` will be sent to our adapter.
|
At this point any requests made by the session to a URI starting with `mock://` will be sent to our adapter.
|
||||||
|
|
||||||
|
|
||||||
Registering Responses
|
|
||||||
=====================
|
|
||||||
|
|
||||||
Responses are registered with the :py:meth:`requests_mock.Adapter.register_uri` function on the adapter.
|
|
||||||
|
|
||||||
.. doctest::
|
|
||||||
|
|
||||||
>>> adapter.register_uri('GET', 'mock://test.com', text='Success')
|
|
||||||
>>> resp = session.get('mock://test.com')
|
|
||||||
>>> resp.text
|
|
||||||
'Success'
|
|
||||||
|
|
||||||
:py:meth:`~requests_mock.Adapter.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.
|
|
||||||
|
|
||||||
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 :py:class:`urllib3.response.HTTPResponse` to be returned.
|
|
||||||
|
|
||||||
These options are named to coincide with the parameters on a :py:class:`requests.Response` object. For example:
|
|
||||||
|
|
||||||
.. doctest::
|
|
||||||
|
|
||||||
>>> 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
|
|
||||||
|
|
||||||
.. code:: python
|
|
||||||
|
|
||||||
def callback(request, context):
|
|
||||||
|
|
||||||
and return a value suitable to the body element that was specified.
|
|
||||||
The elements provided are:
|
|
||||||
|
|
||||||
:request: The :py:class:`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.
|
|
||||||
|
|
||||||
These parameters are populated initially from the variables provided to the :py:meth:`~requests_mock.Adapter.register_uri` function and if they are modified on the context object then those changes will be reflected in the response.
|
|
||||||
|
|
||||||
.. doctest::
|
|
||||||
|
|
||||||
>>> 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.
|
|
||||||
|
|
||||||
.. doctest::
|
|
||||||
|
|
||||||
>>> 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')
|
|
||||||
|
|
||||||
Mock Returns
|
|
||||||
============
|
|
||||||
|
|
||||||
The object returned from a :py:meth:`~requests_mock.Adapter.register_uri` is an object representing the mock that was created at that URL.
|
|
||||||
There are a couple of queries that can be made of this object, including `called` and `call_count`.
|
|
||||||
|
|
||||||
.. doctest::
|
|
||||||
|
|
||||||
>>> mock_obj = adapter.register_uri('GET', 'mock://test.com/5', text='resp')
|
|
||||||
>>> resp = session.get('mock://test.com/5')
|
|
||||||
>>> resp.text
|
|
||||||
'resp'
|
|
||||||
>>> mock_obj.called
|
|
||||||
True
|
|
||||||
>>> mock_obj.call_count
|
|
||||||
1
|
|
||||||
|
|
||||||
.. _requests: http://python-requests.org
|
.. _requests: http://python-requests.org
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ requests_mock.exceptions module
|
|||||||
requests_mock.fixture module
|
requests_mock.fixture module
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
.. automodule:: requests_mock.fixture
|
.. automodule:: requests_mock.contrib.fixture
|
||||||
:members:
|
:members:
|
||||||
:undoc-members:
|
:undoc-members:
|
||||||
:show-inheritance:
|
:show-inheritance:
|
||||||
|
|||||||
47
docs/history.rst
Normal file
47
docs/history.rst
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
===============
|
||||||
|
Request History
|
||||||
|
===============
|
||||||
|
|
||||||
|
The object returned from creating a mock or registering a URI in an adapter is capable of tracking and querying the history of requests that this mock responded to.
|
||||||
|
|
||||||
|
Called
|
||||||
|
======
|
||||||
|
|
||||||
|
The easiest way to test if a request hit the adapter is to simply check the called property.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> import requests
|
||||||
|
>>> import requests_mock
|
||||||
|
|
||||||
|
>>> with requests_mock.mock() as m:
|
||||||
|
... m.get('http://test.com, text='resp')
|
||||||
|
... resp = requests.get('http://test.com')
|
||||||
|
...
|
||||||
|
>>> m.called
|
||||||
|
True
|
||||||
|
>>> m.call_count
|
||||||
|
1
|
||||||
|
|
||||||
|
Request Objects
|
||||||
|
===============
|
||||||
|
|
||||||
|
The history of objects that passed through the `mocker`/`adapter` can also be retrieved
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> history = m.request_history
|
||||||
|
>>> len(history)
|
||||||
|
1
|
||||||
|
>>> history[0].method
|
||||||
|
'GET'
|
||||||
|
>>> history[0].url
|
||||||
|
'http://test.com/'
|
||||||
|
|
||||||
|
This request history object is a wrapper around a standard :py:class:`requests.Request` object with some additional information that make the interface more workable (as the :py:class:`~requests.Request` object is generally not dealt with by users.
|
||||||
|
|
||||||
|
These additions include:
|
||||||
|
|
||||||
|
:text: The data of the request converted into a unicode string.
|
||||||
|
:json: The data of the request loaded from json into python objects.
|
||||||
|
:qs: The query string of the request. See :py:meth:`urllib.parse.parse_qs` for information on the return format.
|
||||||
@@ -8,9 +8,11 @@ Contents:
|
|||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
overview
|
overview
|
||||||
adapter
|
|
||||||
matching
|
|
||||||
mocker
|
mocker
|
||||||
|
matching
|
||||||
|
response
|
||||||
|
history
|
||||||
|
adapter
|
||||||
contrib
|
contrib
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
|
|||||||
@@ -14,8 +14,20 @@ The examples in this file are loaded with:
|
|||||||
>>> session = requests.Session()
|
>>> session = requests.Session()
|
||||||
>>> session.mount('mock', adapter)
|
>>> session.mount('mock', adapter)
|
||||||
|
|
||||||
Basic
|
.. note::
|
||||||
=====
|
|
||||||
|
The examples within use this syntax because request matching 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
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
mock.get(url, ...)
|
||||||
|
|
||||||
|
form in place of the given:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
adapter.register_uri('GET', url, ...)
|
||||||
|
|
||||||
.. doctest::
|
.. doctest::
|
||||||
:hide:
|
:hide:
|
||||||
@@ -26,6 +38,22 @@ Basic
|
|||||||
>>> session = requests.Session()
|
>>> session = requests.Session()
|
||||||
>>> session.mount('mock', adapter)
|
>>> session.mount('mock', adapter)
|
||||||
|
|
||||||
|
Simple
|
||||||
|
======
|
||||||
|
|
||||||
|
The most simple way to match a request is to register the URL and method that will be requested with a textual response.
|
||||||
|
When a request is made that goes through the mocker this response will be retrieved.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
.. >>> adapter.register_uri('GET', 'mock://test.com/path', text='resp')
|
||||||
|
.. >>> session.get('mock://test.com/path').text
|
||||||
|
.. 'resp'
|
||||||
|
|
||||||
|
Path Matching
|
||||||
|
=============
|
||||||
|
|
||||||
|
|
||||||
You can specify a protocol-less path:
|
You can specify a protocol-less path:
|
||||||
|
|
||||||
.. doctest::
|
.. doctest::
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
==============
|
================
|
||||||
Mocker Loading
|
Using the Mocker
|
||||||
==============
|
================
|
||||||
|
|
||||||
Loading of the Adapter is handled by the :py:class:`requests_mock.Mocker` class, which provides two ways to load an adapter.
|
The mocker is a loading mechanism to ensure the adapter is correctly in place to intercept calls from requests.
|
||||||
|
It's goal is to provide an interface that is as close to the real requests library interface as possible.
|
||||||
|
|
||||||
|
Activation
|
||||||
|
==========
|
||||||
|
|
||||||
|
Loading of the Adapter is handled by the :py:class:`requests_mock.Mocker` class, which provides two ways to load an adapter:
|
||||||
|
|
||||||
Context Manager
|
Context Manager
|
||||||
===============
|
---------------
|
||||||
|
|
||||||
The Mocker object can work as a context manager.
|
The Mocker object can work as a context manager.
|
||||||
|
|
||||||
@@ -15,13 +21,13 @@ The Mocker object can work as a context manager.
|
|||||||
>>> import requests_mock
|
>>> import requests_mock
|
||||||
|
|
||||||
>>> with requests_mock.Mocker() as m:
|
>>> with requests_mock.Mocker() as m:
|
||||||
... m.register_uri('GET', 'http://test.com', text='resp')
|
... m.get('http://test.com', text='resp')
|
||||||
... requests.get('http://test.com').text
|
... requests.get('http://test.com').text
|
||||||
...
|
...
|
||||||
'resp'
|
'resp'
|
||||||
|
|
||||||
Decorator
|
Decorator
|
||||||
=========
|
---------
|
||||||
|
|
||||||
Mocker can also be used as a decorator. The created object will then be passed as the last positional argument.
|
Mocker can also be used as a decorator. The created object will then be passed as the last positional argument.
|
||||||
|
|
||||||
@@ -29,7 +35,7 @@ Mocker can also be used as a decorator. The created object will then be passed a
|
|||||||
|
|
||||||
>>> @requests_mock.Mocker()
|
>>> @requests_mock.Mocker()
|
||||||
... def test_function(m):
|
... def test_function(m):
|
||||||
... m.register_uri('GET', 'http://test.com', text='resp')
|
... m.get('http://test.com', text='resp')
|
||||||
... return requests.get('http://test.com').text
|
... return requests.get('http://test.com').text
|
||||||
...
|
...
|
||||||
>>> test_function()
|
>>> test_function()
|
||||||
@@ -41,7 +47,7 @@ If the position of the mock is likely to conflict with other arguments you can p
|
|||||||
|
|
||||||
>>> @requests_mock.Mocker(kw='mock')
|
>>> @requests_mock.Mocker(kw='mock')
|
||||||
... def test_kw_function(**kwargs):
|
... def test_kw_function(**kwargs):
|
||||||
... kwargs['mock'].register_uri('GET', 'http://test.com', text='resp')
|
... kwargs['mock'].get('http://test.com', text='resp')
|
||||||
... return requests.get('http://test.com').text
|
... return requests.get('http://test.com').text
|
||||||
...
|
...
|
||||||
>>> test_kw_function()
|
>>> test_kw_function()
|
||||||
@@ -81,7 +87,7 @@ This behavior mimics how patchers from `mock` library works.
|
|||||||
Methods
|
Methods
|
||||||
=======
|
=======
|
||||||
|
|
||||||
The mocker object can be used with a similar interface to requests itself. Mocker objects can be called with simply the
|
The mocker object can be used with a similar interface to requests itself.
|
||||||
|
|
||||||
.. doctest::
|
.. doctest::
|
||||||
|
|
||||||
@@ -102,10 +108,13 @@ The functions exist for the common HTTP method:
|
|||||||
- :py:meth:`~requests_mock.MockerCore.post`
|
- :py:meth:`~requests_mock.MockerCore.post`
|
||||||
- :py:meth:`~requests_mock.MockerCore.put`
|
- :py:meth:`~requests_mock.MockerCore.put`
|
||||||
|
|
||||||
As well as the base:
|
As well as the basic:
|
||||||
|
|
||||||
- :py:meth:`~requests_mock.MockerCore.request`
|
- :py:meth:`~requests_mock.MockerCore.request`
|
||||||
|
- :py:meth:`~requests_mock.MockerCore.register_uri`
|
||||||
|
|
||||||
|
These methods correspond to the HTTP method of your request, so to mock POST requests you would use the :py:meth:`~requests_mock.MockerCore.post` function.
|
||||||
|
Futher information about what can be matched from a request can be found at :doc:`matching`
|
||||||
|
|
||||||
Real HTTP Requests
|
Real HTTP Requests
|
||||||
==================
|
==================
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ These adapters allow you to register your own handlers for different URIs or pro
|
|||||||
The *requests-mock* library at its core is simply a transport adapter that can be preloaded with responses that are returned if certain URIs are requested.
|
The *requests-mock* library at its core is simply a transport adapter that can be preloaded with responses that are returned if certain URIs are requested.
|
||||||
This is particularly useful in unit tests where you want to return known responses from HTTP requests without making actual calls.
|
This is particularly useful in unit tests where you want to return known responses from HTTP requests without making actual calls.
|
||||||
|
|
||||||
As the `requests`_ library has very limited options for how to load and use adapters *requests-mock* also provides a number (currently 1) of ways that to make sure the mock adapter is used.
|
As the `requests`_ library has very limited options for how to load and use adapters *requests-mock* also provides a number of ways to make sure the mock adapter is used.
|
||||||
These are only loading mechanisms, they do not contain any logic and can be used as a reference to load the adapter in whatever ways works best for your project.
|
These are only loading mechanisms, they do not contain any logic and can be used as a reference to load the adapter in whatever ways works best for your project.
|
||||||
|
|
||||||
.. _requests: http://python-requests.org
|
.. _requests: http://python-requests.org
|
||||||
|
|||||||
132
docs/response.rst
Normal file
132
docs/response.rst
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
==================
|
||||||
|
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
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
mock.get(url, ...)
|
||||||
|
|
||||||
|
form in place of the given:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
adapter.register_uri('GET', url, ...)
|
||||||
|
|
||||||
|
Registering Responses
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Responses are registered with the :py:meth:`requests_mock.Adapter.register_uri` function on the adapter.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> adapter.register_uri('GET', 'mock://test.com', text='Success')
|
||||||
|
>>> resp = session.get('mock://test.com')
|
||||||
|
>>> resp.text
|
||||||
|
'Success'
|
||||||
|
|
||||||
|
:py:meth:`~requests_mock.Adapter.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.
|
||||||
|
|
||||||
|
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 :py:class:`urllib3.response.HTTPResponse` to be returned.
|
||||||
|
|
||||||
|
These options are named to coincide with the parameters on a :py:class:`requests.Response` object. For example:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> 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
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
def callback(request, context):
|
||||||
|
|
||||||
|
and return a value suitable to the body element that was specified.
|
||||||
|
The elements provided are:
|
||||||
|
|
||||||
|
:request: The :py:class:`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.
|
||||||
|
|
||||||
|
These parameters are populated initially from the variables provided to the :py:meth:`~requests_mock.Adapter.register_uri` function and if they are modified on the context object then those changes will be reflected in the response.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> 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.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> 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;
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> 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')
|
||||||
Reference in New Issue
Block a user