
When matching URLs both strings are always lowercased to provide case insensitive matching. Whilst this makes sense for the protocol and the host names it does not necessarily hold true for paths and query strings. A byproduct of this is that the lowercased strings are being reported in request_history which makes it harder to verify requests you made. We enable globally and per adapter setting case sensitive matching. This is intended to become the default in future releases. Change-Id: I7bde70a52995ecf31a0eaeff96f2823a1a6682b2 Closes-Bug: #1584008
7.3 KiB
Request Matching
Whilst it is preferable to provide the whole URI to :pyrequests_mock.Adapter.register_uri
it is possible to
just specify components.
The examples in this file are loaded with:
>>> import requests >>> import requests_mock >>> adapter = requests_mock.Adapter() >>> session = requests.Session() >>> session.mount('mock', adapter)
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
mock.get(url, ...)
form in place of the given:
'GET', url, ...) adapter.register_uri(
>>> import requests >>> import requests_mock >>> adapter = requests_mock.Adapter() >>> session = requests.Session() >>> session.mount('mock', adapter)
Note
By default all matching is case insensitive. This can be adjusted by passing case_sensitive=True when creating a mocker or adapter or globally by doing:
= True requests_mock.mock.case_sensitive
for more see: case_insensitive
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.
Path Matching
You can specify a protocol-less path:
or you can specify just a path:
Query Strings
>>> 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.
>>> adapter.register_uri('GET', '/7?a=1', text='resp') >>> session.get('mock://test.com/7?a=1&b=2').text 'resp'
If any part of the query string is wrong then it will not match.
>>> session.get('mock://test.com/7?a=3') Traceback (most recent call last): ... requests_mock.exceptions.NoMockAddress: No mock address: GET mock://test.com/7?a=3
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`:
>>> adapter.register_uri('GET', '/8?a=1', complete_qs=True, text='resp') >>> session.get('mock://test.com/8?a=1&b=2') Traceback (most recent call last): ... requests_mock.exceptions.NoMockAddress: No mock address: GET mock://test.com/8?a=1&b=2
Matching ANY
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.
>>> import requests >>> import requests_mock >>> adapter = requests_mock.Adapter() >>> session = requests.Session() >>> session.mount('mock', adapter)
>>> adapter.register_uri(requests_mock.ANY, 'mock://test.com/8', text='resp') >>> session.get('mock://test.com/8').text 'resp' >>> session.post('mock://test.com/8').text 'resp'
>>> adapter.register_uri(requests_mock.ANY, requests_mock.ANY, text='resp') >>> session.get('mock://whatever/you/like').text 'resp' >>> session.post('mock://whatever/you/like').text 'resp'
Regular Expressions
URLs can be specified with a regular expression using the python
:pyre
module. To use
this you should pass an object created by :pyre.compile
.
The URL is then matched using :pyre.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.
>>> import requests >>> import requests_mock >>> adapter = requests_mock.Adapter() >>> session = requests.Session() >>> session.mount('mock', adapter)
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.
Request Headers
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.
>>> import requests >>> import requests_mock >>> adapter = requests_mock.Adapter() >>> session = requests.Session() >>> session.mount('mock', adapter)
>>> 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/headers') Traceback (most recent call last): ... requests_mock.exceptions.NoMockAddress: No mock address: POST mock://test.com/headers
Custom Matching
Internally calling :py~requests_mock.Adapter.register_uri
creates a
matcher object for you and adds it to the list of matchers to
check against.
A matcher is any callable that takes a :pyrequests.Request
and
returns a :pyrequests.Response
on a successful match or
None if it does not handle the request.
If you need more flexibility than provided by :py~requests_mock.Adapter.register_uri
then you can add
your own matcher to the :py~requests_mock.Adapter
. Custom matchers can
be used in conjunction with the inbuilt matchers. If a matcher
returns None then the request will be passed to the next
matcher as with using :py~requests_mock.Adapter.register_uri
.
>>> import requests >>> import requests_mock >>> adapter = requests_mock.Adapter() >>> session = requests.Session() >>> session.mount('mock', adapter)
>>> def custom_matcher(request): ... if request.path_url == '/test': ... resp = requests.Response() ... resp.status_code = 200 ... return resp ... return None ... >>> adapter.add_matcher(custom_matcher) >>> session.get('mock://test.com/test').status_code 200 >>> session.get('mock://test.com/other') Traceback (most recent call last): ... requests_mock.exceptions.NoMockAddress: No mock address: POST mock://test.com/other