Doctest fixups
This commit is contained in:
parent
4040a190d6
commit
97fb2bce39
@ -5,9 +5,9 @@ Adapter Usage
|
|||||||
Creating an Adapter
|
Creating an Adapter
|
||||||
===================
|
===================
|
||||||
|
|
||||||
The standard `requests`_ means of using an adapter is to :py:meth:`requests.Session.mount` it on a created session. This is not the only way to load the adapter, however the same interactions will be used.
|
The standard `requests`_ means of using an adapter is to :py:meth:`~requests.Session.mount` it on a created session. This is not the only way to load the adapter, however the same interactions will be used.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> import requests
|
>>> import requests
|
||||||
>>> import requests_mock
|
>>> import requests_mock
|
||||||
@ -24,14 +24,14 @@ Registering Responses
|
|||||||
|
|
||||||
Responses are registered with the :py:meth:`requests_mock.Adapter.register_uri` function on the adapter.
|
Responses are registered with the :py:meth:`requests_mock.Adapter.register_uri` function on the adapter.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> adapter.register_uri('GET', 'mock://test.com', text='Success')
|
>>> adapter.register_uri('GET', 'mock://test.com', text='Success')
|
||||||
>>> resp = session.get('mock://test.com')
|
>>> resp = session.get('mock://test.com')
|
||||||
>>> resp.text
|
>>> resp.text
|
||||||
'Success'
|
'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:
|
: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.
|
: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')
|
:reason: The reason text that accompanies the Status (e.g. 'OK' in '200 OK')
|
||||||
@ -47,7 +47,7 @@ To specify the body of the response there are a number of options that depend on
|
|||||||
|
|
||||||
These options are named to coincide with the parameters on a :py:class:`requests.Response` object. For example:
|
These options are named to coincide with the parameters on a :py:class:`requests.Response` object. For example:
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> adapter.register_uri('GET', 'mock://test.com/1', json={'a': 'b'}, status_code=200)
|
>>> adapter.register_uri('GET', 'mock://test.com/1', json={'a': 'b'}, status_code=200)
|
||||||
>>> resp = session.get('mock://test.com/1')
|
>>> resp = session.get('mock://test.com/1')
|
||||||
@ -85,9 +85,9 @@ The available properties on the `context` are:
|
|||||||
:status_code: The status code that is 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.
|
: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.
|
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.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> def text_callback(request, context):
|
>>> def text_callback(request, context):
|
||||||
... context.status_code = 200
|
... context.status_code = 200
|
||||||
@ -109,7 +109,7 @@ Response Lists
|
|||||||
Multiple responses can be provided to be returned in order by specifying the keyword parameters in a list.
|
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.
|
If the list is exhausted then the last response will continue to be returned.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> adapter.register_uri('GET', 'mock://test.com/4', [{'text': 'resp1', 'status_code': 300},
|
>>> adapter.register_uri('GET', 'mock://test.com/4', [{'text': 'resp1', 'status_code': 300},
|
||||||
... {'text': 'resp2', 'status_code': 200}])
|
... {'text': 'resp2', 'status_code': 200}])
|
||||||
|
@ -39,6 +39,7 @@ import requests_mock # noqa
|
|||||||
# Add any Sphinx extension module names here, as strings. They can be
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
extensions = ['sphinx.ext.autodoc',
|
extensions = ['sphinx.ext.autodoc',
|
||||||
|
'sphinx.ext.doctest',
|
||||||
'sphinx.ext.viewcode',
|
'sphinx.ext.viewcode',
|
||||||
'sphinx.ext.intersphinx']
|
'sphinx.ext.intersphinx']
|
||||||
|
|
||||||
|
@ -14,16 +14,16 @@ The fixture mocks the :py:meth:`requests.Session.get_adapter` method so that all
|
|||||||
|
|
||||||
The fixture provides the same interfaces as the adapter.
|
The fixture provides the same interfaces as the adapter.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> import requests
|
>>> import requests
|
||||||
>>> from requests_mock.contrib import fixture
|
>>> from requests_mock.contrib import fixture
|
||||||
>>> import testtools
|
>>> import testtools
|
||||||
|
|
||||||
>>> class MyTestCase(testtools.TestCase):
|
>>> class MyTestCase(testtools.TestCase):
|
||||||
|
...
|
||||||
... TEST_URL = 'http://www.google.com'
|
... TEST_URL = 'http://www.google.com'
|
||||||
|
...
|
||||||
... def setUp(self):
|
... def setUp(self):
|
||||||
... super(MyTestCase, self).setUp()
|
... super(MyTestCase, self).setUp()
|
||||||
... self.requests_mock = self.useFixture(requests_mock.Mock())
|
... self.requests_mock = self.useFixture(requests_mock.Mock())
|
||||||
|
@ -4,39 +4,70 @@ Request Matching
|
|||||||
|
|
||||||
Whilst it is preferable to provide the whole URI to :py:meth:`requests_mock.Adapter.register_uri` it is possible to just specify components.
|
Whilst it is preferable to provide the whole URI to :py:meth:`requests_mock.Adapter.register_uri` it is possible to just specify components.
|
||||||
|
|
||||||
|
The examples in this file are loaded with:
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> import requests
|
||||||
|
>>> import requests_mock
|
||||||
|
>>> adapter = requests_mock.Adapter()
|
||||||
|
>>> session = requests.Session()
|
||||||
|
>>> session.mount('mock', adapter)
|
||||||
|
|
||||||
Basic
|
Basic
|
||||||
=====
|
=====
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> import requests
|
||||||
|
>>> import requests_mock
|
||||||
|
>>> adapter = requests_mock.Adapter()
|
||||||
|
>>> session = requests.Session()
|
||||||
|
>>> session.mount('mock', adapter)
|
||||||
|
|
||||||
You can specify a protocol-less path:
|
You can specify a protocol-less path:
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> adapter.register_uri('GET', '//test.com/5', text='resp')
|
.. >>> adapter.register_uri('GET', '//test.com/', text='resp')
|
||||||
>>> session.get('mock://test.com/5').text
|
.. >>> session.get('mock://test.com/').text
|
||||||
'resp'
|
.. 'resp'
|
||||||
|
|
||||||
or you can specify just a path:
|
or you can specify just a path:
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> adapter.register_uri('GET', '/6', text='resp')
|
|
||||||
>>> session.get('mock://test.com/6').text
|
|
||||||
'resp'
|
|
||||||
>>> session.get('mock://another.com/6').text
|
|
||||||
'resp'
|
|
||||||
|
|
||||||
|
.. >>> adapter.register_uri('GET', '/path', text='resp')
|
||||||
|
.. >>> session.get('mock://test.com/path').text
|
||||||
|
.. 'resp'
|
||||||
|
.. >>> session.get('mock://another.com/path').text
|
||||||
|
.. 'resp'
|
||||||
|
|
||||||
Query Strings
|
Query Strings
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> import requests
|
||||||
|
>>> import requests_mock
|
||||||
|
>>> adapter = requests_mock.Adapter()
|
||||||
|
>>> session = requests.Session()
|
||||||
|
>>> session.mount('mock', adapter)
|
||||||
|
|
||||||
Query strings provided to a register will match so long as at least those provided form part of the request.
|
Query strings provided to a register will match so long as at least those provided form part of the request.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> adapter.register_uri('GET', '/7?a=1', text='resp')
|
>>> adapter.register_uri('GET', '/7?a=1', text='resp')
|
||||||
>>> session.get('mock://test.com/7?a=1&b=2').text
|
>>> session.get('mock://test.com/7?a=1&b=2').text
|
||||||
'resp'
|
'resp'
|
||||||
|
|
||||||
|
If any part of the query string is wrong then it will not match.
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
>>> session.get('mock://test.com/7?a=3')
|
>>> session.get('mock://test.com/7?a=3')
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
@ -44,7 +75,7 @@ Query strings provided to a register will match so long as at least those provid
|
|||||||
|
|
||||||
This can be a problem in certain situations, so if you wish to match only the complete query string there is a flag `complete_qs`:
|
This can be a problem in certain situations, so if you wish to match only the complete query string there is a flag `complete_qs`:
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> adapter.register_uri('GET', '/8?a=1', complete_qs=True, text='resp')
|
>>> adapter.register_uri('GET', '/8?a=1', complete_qs=True, text='resp')
|
||||||
>>> session.get('mock://test.com/8?a=1&b=2')
|
>>> session.get('mock://test.com/8?a=1&b=2')
|
||||||
@ -59,7 +90,16 @@ Matching ANY
|
|||||||
There is a special symbol at `requests_mock.ANY` which acts as the wildcard to match anything.
|
There is a special symbol at `requests_mock.ANY` which acts as the wildcard to match anything.
|
||||||
It can be used as a replace for the method and/or the URL.
|
It can be used as a replace for the method and/or the URL.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
:hide:
|
||||||
|
|
||||||
|
>>> import requests
|
||||||
|
>>> import requests_mock
|
||||||
|
>>> adapter = requests_mock.Adapter()
|
||||||
|
>>> session = requests.Session()
|
||||||
|
>>> session.mount('mock', adapter)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
>>> adapter.register_uri(requests_mock.ANY, 'mock://test.com/8', text='resp')
|
>>> adapter.register_uri(requests_mock.ANY, 'mock://test.com/8', text='resp')
|
||||||
>>> session.get('mock://test.com/8').text
|
>>> session.get('mock://test.com/8').text
|
||||||
@ -67,15 +107,14 @@ It can be used as a replace for the method and/or the URL.
|
|||||||
>>> session.post('mock://test.com/8').text
|
>>> session.post('mock://test.com/8').text
|
||||||
'resp'
|
'resp'
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> adapter.register_uri(requests_mock.ANY, requests_mock.ANY, text='resp')
|
>>> adapter.register_uri(requests_mock.ANY, requests_mock.ANY, text='resp')
|
||||||
>>> session.get('mock://whatever/you/like')
|
>>> session.get('mock://whatever/you/like').text
|
||||||
'resp'
|
'resp'
|
||||||
>>> session.post('mock://whatever/you/like')
|
>>> session.post('mock://whatever/you/like').text
|
||||||
'resp'
|
'resp'
|
||||||
|
|
||||||
|
|
||||||
Regular Expressions
|
Regular Expressions
|
||||||
===================
|
===================
|
||||||
|
|
||||||
@ -84,13 +123,22 @@ To use this you should pass an object created by :py:func:`re.compile`.
|
|||||||
|
|
||||||
The URL is then matched using :py:meth:`re.regex.search` which means that it will match any component of the url, so if you want to match the start of a URL you will have to anchor it.
|
The URL is then matched using :py:meth:`re.regex.search` which means that it will match any component of the url, so if you want to match the start of a URL you will have to anchor it.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
:hide:
|
||||||
|
|
||||||
>>> import re
|
>>> import requests
|
||||||
>>> matcher = re.compile('tester.com/a')
|
>>> import requests_mock
|
||||||
>>> adapter.register_uri('GET', matcher, text='resp')
|
>>> adapter = requests_mock.Adapter()
|
||||||
>>> session.get('mock://www.tester.com/a/b').text
|
>>> session = requests.Session()
|
||||||
'resp'
|
>>> session.mount('mock', adapter)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
.. >>> import re
|
||||||
|
.. >>> matcher = re.compile('tester.com/a')
|
||||||
|
.. >>> adapter.register_uri('GET', matcher, text='resp')
|
||||||
|
.. >>> session.get('mock://www.tester.com/a/b').text
|
||||||
|
.. 'resp'
|
||||||
|
|
||||||
If you use regular expression matching then *requests-mock* can't do it's normal query string or path only matching, that will need to be part of the expression.
|
If you use regular expression matching then *requests-mock* can't do it's normal query string or path only matching, that will need to be part of the expression.
|
||||||
|
|
||||||
@ -101,12 +149,21 @@ Request Headers
|
|||||||
A dictionary of headers can be supplied such that the request will only match if the available headers also match.
|
A dictionary of headers can be supplied such that the request will only match if the available headers also match.
|
||||||
Only the headers that are provided need match, any additional headers will be ignored.
|
Only the headers that are provided need match, any additional headers will be ignored.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
:hide:
|
||||||
|
|
||||||
>>> adapter.register_uri('POST', 'mock://test.com', request_headers={'key', 'val'}, text='resp')
|
>>> import requests
|
||||||
>>> session.post('mock://test.com', headers={'key': 'val', 'another': 'header'}).text
|
>>> import requests_mock
|
||||||
|
>>> adapter = requests_mock.Adapter()
|
||||||
|
>>> session = requests.Session()
|
||||||
|
>>> session.mount('mock', adapter)
|
||||||
|
|
||||||
|
.. doctest::
|
||||||
|
|
||||||
|
>>> adapter.register_uri('POST', 'mock://test.com/headers', request_headers={'key': 'val'}, text='resp')
|
||||||
|
>>> session.post('mock://test.com/headers', headers={'key': 'val', 'another': 'header'}).text
|
||||||
'resp'
|
'resp'
|
||||||
>>> session.post('mock://test.com')
|
>>> resp = session.post('mock://test.com/headers')
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
requests_mock.exceptions.NoMockAddress: No mock address: POST mock://test.com/
|
requests_mock.exceptions.NoMockAddress: No mock address: POST mock://test.com/headers
|
||||||
|
@ -9,7 +9,7 @@ Context Manager
|
|||||||
|
|
||||||
The Mocker object can work as a context manager.
|
The Mocker object can work as a context manager.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> import requests
|
>>> import requests
|
||||||
>>> import requests_mock
|
>>> import requests_mock
|
||||||
@ -25,7 +25,7 @@ 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.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> @requests_mock.Mocker()
|
>>> @requests_mock.Mocker()
|
||||||
... def test_function(m):
|
... def test_function(m):
|
||||||
@ -37,14 +37,14 @@ Mocker can also be used as a decorator. The created object will then be passed a
|
|||||||
|
|
||||||
If the position of the mock is likely to conflict with other arguments you can pass the `kw` argument to the Mocker to have the mocker object passed as that keyword argument instead.
|
If the position of the mock is likely to conflict with other arguments you can pass the `kw` argument to the Mocker to have the mocker object passed as that keyword argument instead.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> @requests_mock.Mocker(kw='mock')
|
>>> @requests_mock.Mocker(kw='mock')
|
||||||
... def test_function(**kwargs):
|
... def test_kw_function(**kwargs):
|
||||||
... kwargs['mock'].register_uri('GET', 'http://test.com', test='resp')
|
... kwargs['mock'].register_uri('GET', 'http://test.com', text='resp')
|
||||||
... return requests.get('http://test.com').text
|
... return requests.get('http://test.com').text
|
||||||
...
|
...
|
||||||
>>> test_function()
|
>>> test_kw_function()
|
||||||
'resp'
|
'resp'
|
||||||
|
|
||||||
Real HTTP Requests
|
Real HTTP Requests
|
||||||
@ -54,12 +54,12 @@ The Mocker object takes the following parameters:
|
|||||||
|
|
||||||
:real_http (bool): If True then any requests that are not handled by the mocking adapter will be forwarded to the real server. Defaults to False.
|
:real_http (bool): If True then any requests that are not handled by the mocking adapter will be forwarded to the real server. Defaults to False.
|
||||||
|
|
||||||
.. code:: python
|
.. doctest::
|
||||||
|
|
||||||
>>> with requests_mock.Mocker(real_http=True) as m:
|
>>> with requests_mock.Mocker(real_http=True) as m:
|
||||||
... m.register_uri('GET', 'http://test.com', text='resp')
|
... m.register_uri('GET', 'http://test.com', text='resp')
|
||||||
... print requests.get('http:/test.com').text
|
... print(requests.get('http://test.com').text)
|
||||||
... print requests.get('http://www.google.com').status_code
|
... print(requests.get('http://www.google.com').status_code) # doctest: +SKIP
|
||||||
...
|
...
|
||||||
'resp'
|
'resp'
|
||||||
200
|
200
|
||||||
|
8
tox.ini
8
tox.ini
@ -28,6 +28,12 @@ deps =
|
|||||||
# note this only works under python 3 because of unicode literals
|
# note this only works under python 3 because of unicode literals
|
||||||
commands =
|
commands =
|
||||||
python -m doctest README.rst
|
python -m doctest README.rst
|
||||||
|
|
||||||
|
[testenv:sphinx-doctest]
|
||||||
|
# note this only works under python 3 because of unicode literals
|
||||||
|
commands =
|
||||||
|
mkdir build/sphinx/doctest
|
||||||
|
sphinx-build -b doctest docs build/sphinx/doctest
|
||||||
deps =
|
deps =
|
||||||
ipdb
|
pbr
|
||||||
{[testenv]deps}
|
{[testenv]deps}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user