responses
A utility library for mocking out the `requests` Python library.
Downloads: 0 (30 days)
Description
Responses
=========
.. image:: https://img.shields.io/pypi/v/responses.svg
:target: https://pypi.python.org/pypi/responses/
.. image:: https://img.shields.io/pypi/pyversions/responses.svg
:target: https://pypi.org/project/responses/
.. image:: https://img.shields.io/pypi/dm/responses
:target: https://pypi.python.org/pypi/responses/
.. image:: https://codecov.io/gh/getsentry/responses/branch/master/graph/badge.svg
:target: https://codecov.io/gh/getsentry/responses/
A utility library for mocking out the ``requests`` Python library.
.. note::
Responses requires Python 3.8 or newer, and requests >= 2.30.0
Table of Contents
-----------------
.. contents::
Installing
----------
``pip install responses``
Deprecations and Migration Path
-------------------------------
Here you will find a list of deprecated functionality and a migration path for each.
Please ensure to update your code according to the guidance.
.. list-table:: Deprecation and Migration
:widths: 50 25 50
:header-rows: 1
* - Deprecated Functionality
- Deprecated in Version
- Migration Path
* - ``responses.json_params_matcher``
- 0.14.0
- ``responses.matchers.json_params_matcher``
* - ``responses.urlencoded_params_matcher``
- 0.14.0
- ``responses.matchers.urlencoded_params_matcher``
* - ``stream`` argument in ``Response`` and ``CallbackResponse``
- 0.15.0
- Use ``stream`` argument in request directly.
* - ``match_querystring`` argument in ``Response`` and ``CallbackResponse``.
- 0.17.0
- Use ``responses.matchers.query_param_matcher`` or ``responses.matchers.query_string_matcher``
* - ``responses.assert_all_requests_are_fired``, ``responses.passthru_prefixes``, ``responses.target``
- 0.20.0
- Use ``responses.mock.assert_all_requests_are_fired``,
``responses.mock.passthru_prefixes``, ``responses.mock.target`` instead.
Basics
------
The core of ``responses`` comes from registering mock responses and covering test function
with ``responses.activate`` decorator. ``responses`` provides similar interface as ``requests``.
Main Interface
^^^^^^^^^^^^^^
* responses.add(``Response`` or ``Response args``) - allows either to register ``Response`` object or directly
provide arguments of ``Response`` object. See `Response Parameters`_
.. code-block:: python
import responses
import requests
@responses.activate
def test_simple():
# Register via 'Response' object
rsp1 = responses.Response(
method="PUT",
url="http://example.com",
)
responses.add(rsp1)
# register via direct arguments
responses.add(
responses.GET,
"http://twitter.com/api/1/foobar",
json={"error": "not found"},
status=404,
)
resp = requests.get("http://twitter.com/api/1/foobar")
resp2 = requests.put("http://example.com")
assert resp.json() == {"error": "not found"}
assert resp.status_code == 404
assert resp2.status_code == 200
assert resp2.request.method == "PUT"
If you attempt to fetch a url which doesn't hit a match, ``responses`` will raise
a ``ConnectionError``:
.. code-block:: python
import responses
import requests
from requests.exceptions import ConnectionError
@responses.activate
def test_simple():
with pytest.raises(ConnectionError):
requests.get("http://twitter.com/api/1/foobar")
Shortcuts
^^^^^^^^^
Shortcuts provide a shorten version of ``responses.add()`` where method argument is prefilled
* responses.delete(``Response args``) - register DELETE response
* responses.get(``Response args``) - register GET response
* responses.head(``Response args``) - register HEAD response
* responses.options(``Response args``) - register OPTIONS response
* responses.patch(``Response args``) - register PATCH response
* responses.post(``Response args``) - register POST response
* responses.put(``Response args``) - register PUT response
.. code-block:: python
import responses
import requests
@responses.activate
def test_simple():
responses.get(
"http://twitter.com/api/1/foobar",
json={"type": "get"},
)
responses.post(
"http://twitter.com/api/1/foobar",
json={"type": "post"},
)
responses.patch(
"http://twitter.com/api/1/foobar",
json={"type": "patch"},
)
resp_get = requests.get("http://twitter.com/api/1/foobar")
resp_post = requests.post("http://twitter.com/api/1/foobar")
resp_patch = requests.patch("http://twitter.com/api/1/foobar")
assert resp_get.json() == {"type": "get"}
assert resp_post.json() == {"type": "post"}
assert resp_patch.json() == {"type": "patch"}
Responses as a context manager
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Instead of wrapping the whole function with decorator you can use a context manager.
.. code-block:: python
import responses
import requests
def test_my_api():
with responses.RequestsMock() as rsps:
rsps.add(
responses.GET,
"http://twitter.com/api/1/foobar",
body="{}",
status=200,
content_type="application/json",
)
resp = requests.get("http://twitter.com/api/1/foobar")
assert resp.status_code == 200
# outside the context manager requests will hit the remote server
resp = requests.get("http://twitter.com/api/1/foobar")
resp.status_code == 404
Response Parameters
-------------------
The following attributes can be passed to a Response mock:
method (``str``)
The HTTP method (GET, POST, etc).
url (``str`` or ``compiled regular expression``)
The full resource URL.
match_querystring (``bool``)
DEPRECATED: Use ``responses.matchers.query_param_matcher`` or
``responses.matchers.query_string_matcher``
Include the query string when matching requests.
Enabled by default if the response URL contains a query string,
disabled if it doesn't or the URL is a regular expression.
body (``str`` or ``BufferedReader`` or ``Exception``)
The response body. Read more `Exception as Response body`_
json
A Python object representing the JSON response body. Automatically configures
the appropriate Content-Type.
status (``int``)
The HTTP status code.
content_type (``content_type``)
Defaults to ``text/plain``.
headers (``dict``)
Response headers.
stream (``bool``)
DEPRECATED: use ``stream`` argument in request directly
auto_calculate_content_length (``bool``)
Disabled by default. Automatically calculates the length of a supplied string or JSON body.
match (``tuple``)
An iterable (``tuple`` is recommended) of callbacks to match requests
based on request attributes.
Current module provides multiple matchers that you can use to match:
* body contents in JSON format
* body contents in URL encoded data format
* request query parameters
* request query string (similar to query parameters but takes string as input)
* kwargs provided to request e.g. ``stream``, ``verify``
* 'multipart/form-data' content and headers in request
* request headers
* request fragment identifier
Alternatively user can create custom matcher.
Read more `Matching Requests`_
Exception as Response body
--------------------------
You can pass an ``Exception`` as the body to trigger an error on the request:
.. code-block:: python
import responses
import requests
@responses.activate
def test_simple():
responses.get("http://twitter.com/api/1/foobar", body=Exception("..."))
with pytest.raises(Exception):
requests.get("http://twitter.com/api/1/foobar")
Matching Requests
-----------------
Matching Request Body Contents
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When adding responses for endpoints that are sent request data you can add
matchers to ensure your code is sending the right parameters and provide
different responses based on the request body contents. ``responses`` provides
matchers for JSON and URL-encoded request bodies.
URL-encoded data
""""""""""""""""
.. code-block:: python
import responses
import requests
from responses import matchers
@responses.activate
def test_calc_api():
responses.post(
url="http://calc.com/sum",
body="4",
match=[matchers.urlencoded_params_matcher({"left": "1", "right": "3"})],
)
requests.post("http://calc.com/sum", data={"left": 1, "right": 3})
JSON encoded data
"""""""""""""""""
Matching JSON encoded data can be done with ``matchers.json_params_matcher()``.
.. code-block:: python
import responses
import requests
from responses import matchers
@responses.activate
def test_calc_api():
responses.post(
url="http://example.com/",
body="one",
match=[
matchers.json_params_matcher({"page": {"name": "first", "type": "json"}})
],
)
resp = requests.request(
"POST",
"http://example.com/",
headers={"Content-Type": "application/json"},
json={"page": {"name": "first", "type": "json"}},
)
Query Parameters Matcher
^^^^^^^^^^^^^^^^^^^^^^^^
Query Parameters as a Dictionary
""""""""""""""""""""""""""""""""
You can use the ``matchers.query_param_matcher`` function to match
against the ``params`` request parameter. Just use the same dictionary as you
will use in ``params`` argument in ``request``.
Note, do not use query parameters as part of the URL. Avoid using ``match_querystring``
deprecated argument.
.. code-block:: python
import responses
import requests
from responses