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
importresponsesimportrequests@responses.activatedeftest_simple():# Register via 'Response' objectrsp1=responses.Response(method="PUT",url="http://example.com",)responses.add(rsp1)# register via direct argumentsresponses.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")assertresp.json()=={"error":"not found"}assertresp.status_code==404assertresp2.status_code==200assertresp2.request.method=="PUT"
If you attempt to fetch a url which doesn’t
hit a match, responses will raise a ConnectionError:
Instead of wrapping the whole function with decorator you can use a context manager.
importresponsesimportrequestsdeftest_my_api():withresponses.RequestsMock()asrsps: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")assertresp.status_code==200# outside the context manager requests will hit the remote serverresp=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:
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.
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.
importresponsesimportrequestsfromresponsesimportmatchers@responses.activatedeftest_calc_api():url="http://example.com/test"params={"hello":"world","I am":"a big test"}responses.get(url=url,body="test",match=[matchers.query_param_matcher(params)],)resp=requests.get(url,params=params)constructed_url=r"http://example.com/test?I+am=a+big+test&hello=world"assertresp.url==constructed_urlassertresp.request.url==constructed_urlassertresp.request.params==params
By default, matcher will validate that all parameters match strictly. To validate that only parameters specified in the matcher are present in original request use strict_match=False.
Query Parameters as a String
As alternative, you can use query string value in matchers.query_string_matcher to match query parameters in your request
To validate request body and headers for
multipart/form-data data you can use matchers.multipart_matcher. The data, and files parameters provided will be compared to the request:
To validate request URL fragment identifier you can use
matchers.fragment_identifier_matcher. The matcher takes fragment string (everything after # sign) as input for comparison:
importrequestsimportresponsesfromresponses.matchersimportfragment_identifier_matcher@responses.activatedefrun():url="http://example.com?ab=xy&zed=qwe#test=1&foo=bar"responses.get(url,match=[fragment_identifier_matcher("test=1&foo=bar")],body=b"test",)# two requests to check reversed order of fragment identifierresp=requests.get("http://example.com?ab=xy&zed=qwe#test=1&foo=bar")resp=requests.get("http://example.com?zed=qwe&ab=xy#foo=bar&test=1")run()
Creating Custom Matcher
If your application requires other encodings or different data validation you can build your own matcher that returns Tuple[matches: bool, reason:
str]. Where boolean represents True or False if the request parameters match and the string is a reason in case of match failure. Your matcher can expect a PreparedRequest parameter to be provided by responses.
Note, PreparedRequest is customized and has additional attributes params and req_kwargs.
Response Registry
Default Registry
By default, responses will search all registered Response objects and return a match. If only one Response is registered, the registry is kept unchanged. However, if multiple matches are found
for the same request, then first match is returned and removed from registry.
Ordered Registry
In some scenarios it is important to preserve the order of the requests and responses. You can use registries.OrderedRegistry to force all Response objects to be dependent on the insertion order and invocation index. In following
example we add multiple Response objects that target the same URL. However, you can see, that status code will depend on the invocation order.
Built-in registries are suitable for most of use cases, but to handle special conditions, you can implement custom registry which must follow interface of
registries.FirstMatchRegistry. Redefining the find method will allow you to create custom search logic and return appropriate Response
Example that shows how to set custom registry
importresponsesfromresponsesimportregistriesclassCustomRegistry(registries.FirstMatchRegistry):passprint("Before tests:",responses.mock.get_registry())""" Before tests: """# using function decorator@responses.activate(registry=CustomRegistry)defrun():print("Within test:",responses.mock.get_registry())""" Within test: <__main__.CustomRegistry object> """run()print("After test:",responses.mock.get_registry())""" After test: """# using context managerwithresponses.RequestsMock(registry=CustomRegistry)asrsps:print("In context manager:",rsps.get_registry())""" In context manager: <__main__.CustomRegistry object> """print("After exit from context manager:",responses.mock.get_registry())"""
After exit from context manager:
"""
Dynamic Responses
You can utilize callbacks to provide dynamic responses. The callback must return a tuple
of (status, headers, body).
If you want to pass extra keyword arguments to the callback function, for example when reusing a callback function to give a slightly different result, you can use functools.partial:
When run with unittest tests, this can be used to set up some generic class-level responses, that may be complemented by each test. Similar interface could be applied in pytest framework.
classTestMyApi(unittest.TestCase):defsetUp(self):responses.get("https://example.com",body="within setup")# here go other self.responses.add(...)@responses.activatedeftest_my_func(self):responses.get("https://httpbin.org/get",match=[matchers.query_param_matcher({"test":"1","didi":"pro"})],body="within test",)resp=requests.get("https://example.com")resp2=requests.get("https://httpbin.org/get",params={"test":"1","didi":"pro"})print(resp.text)# >>> within setupprint(resp2.text)# >>> within test
RequestMock methods: start, stop, reset
responses has
start, stop, reset methods very analogous to unittest.mock.patch. These make it simpler to do requests mocking in setup methods or where you want to do multiple patches without nesting decorators or with statements.
classTestUnitTestPatchSetup:defsetup(self):"""Creates ``RequestsMock`` instance and starts it."""self.r_mock=responses.RequestsMock(assert_all_requests_are_fired=True)self.r_mock.start()# optionally some default responses could be registeredself.r_mock.get("https://example.com",status=505)self.r_mock.put("https://example.com",status=506)defteardown(self):"""Stops and resets RequestsMock instance.
If ``assert_all_requests_are_fired`` is set to ``True``, will raise an error
if some requests were not processed.
"""self.r_mock.stop()self.r_mock.reset()deftest_function(self):resp=requests.get("https://example.com")assertresp.status_code==505resp=requests.put("https://example.com")assertresp.status_code==506
Assertions on declared responses
When used as a context manager, Responses will, by default, raise an assertion error if a url was registered but not accessed. This can be disabled by passing the assert_all_requests_are_fired value:
Assert that the request was called exactly n times.
importresponsesimportrequests@responses.activatedeftest_assert_call_count():responses.get("http://example.com")requests.get("http://example.com")assertresponses.assert_call_count("http://example.com",1)isTruerequests.get("http://example.com")withpytest.raises(AssertionError)asexcinfo:responses.assert_call_count("http://example.com",1)assert("Expected URL 'http://example.com' to be called 1 times. Called 2 times."instr(excinfo.value))@responses.activatedeftest_assert_call_count_always_match_qs():responses.get("http://www.example.com")requests.get("http://www.example.com")requests.get("http://www.example.com?hello=world")# One call on each url, querystring is matched by defaultresponses.assert_call_count("http://www.example.com",1)isTrueresponses.assert_call_count("http://www.example.com?hello=world",1)isTrue
Multiple Responses
You can also add multiple responses for the same url:
In the following example you can see how to create a redirection chain and add custom exception that will be raised in the execution chain and contain the history of redirects.
A -> 301 redirect -> B
B -> 301 redirect -> C
C -> connection issue
importpytestimportrequestsimportresponses@responses.activatedeftest_redirect():# create multiple Response objects where first two contain redirect headersrsp1=responses.Response(responses.GET,"http://example.com/1",status=301,headers={"Location":"http://example.com/2"},)rsp2=responses.Response(responses.GET,"http://example.com/2",status=301,headers={"Location":"http://example.com/3"},)rsp3=responses.Response(responses.GET,"http://example.com/3",status=200)# register above generated Responses in ``response`` moduleresponses.add(rsp1)responses.add(rsp2)responses.add(rsp3)# do the first request in order to generate genuine ``requests`` response# this object will contain genuine attributes of the response, like ``history``rsp=requests.get("http://example.com/1")responses.calls.reset()# customize exception with ``response`` attributemy_error=requests.ConnectionError("custom error")my_error.response=rsp# update body of the 3rd response with Exception, this will be raised during executionrsp3.body=my_errorwithpytest.raises(requests.ConnectionError)asexc_info:requests.get("http://example.com/1")assertexc_info.value.args[0]=="custom error"assertrsp1.urlinexc_info.value.response.history[0].urlassertrsp2.urlinexc_info.value.response.history[1].url
Validate
Retry mechanism
If you are using the Retry features of urllib3 and want to cover scenarios that test your retry limits, you can test those scenarios with responses as well. The best approach will be to use an Ordered Registry
If you use customized processing in requests via subclassing/mixins, or if you have library tools that interact with requests at a low level, you may need to add extended processing to the mocked Response object to fully simulate the environment for your tests. A response_callback can be used, which will be wrapped by the
library before being returned to the caller. The callback accepts a response as it’s single argument, and is expected to return a single response object.
In some cases you may wish to allow for certain requests to pass through responses and hit a real server. This can be
done with the add_passthru methods:
Lastly, you can use the response.passthrough attribute on BaseResponse or use PassthroughResponse to
enable a response to behave as a pass through.
# Enable passthrough for a single responseresponse=Response(responses.GET,"http://example.com",body="not used")response.passthrough=Trueresponses.add(response)# Use PassthroughResponseresponse=PassthroughResponse(responses.GET,"http://example.com")responses.add(response)
Viewing/Modifying registered responses
Registered responses are available as a public method of the RequestMock instance. It is sometimes useful for debugging purposes to view the stack of registered responses which can be accessed via responses.registered().
The replace function allows a previously registered response to be changed. The method signature is identical to add. response s are identified using method and url. Only the first matched response is replaced.
The upsert function allows a previously registered response to be changed like replace. If the response is registered, the upsert
function will registered it like add.
remove takes a method and url argument and will remove all matched responses from the registered list.
Finally, reset will reset all registered responses.
Coroutines and Multithreading
responses
supports both Coroutines and Multithreading out of the box. Note, responses locks threading on RequestMock object allowing only single thread to access it.
The easiest way to validate your code is to run tests via tox. Current tox configuration runs the same checks that are used in GitHub Actions CI/CD pipeline.
Please execute the following command line from the project root to validate your code against:
Unit tests in all Python versions that are supported by this project
Type validation via mypy
All
pre-commit hooks
tox
Alternatively, you can always run a single test. See documentation below.
Unit tests
Responses uses Pytest for testing. You can run all tests by:
tox -e py37
tox -e py310
OR manually activate required version of Python and run
pytest
And run a single test by:
pytest -k ''
Type Validation
To verify type compliance, run mypy linter:
tox -e mypy
OR
mypy --config-file=./mypy.ini -p responses
Code Quality and Style
To check code style and reformat it run:
tox -e precom
OR
pre-commit run --all-files
How do you assign a response to an object in Python?
Just use the responses library to do it for you: import responses @responses.activate def test_my_api(): responses.add(responses.
How do you write a response to a file in python?
When writing responses to file you need to use the open function with the appropriate file write mode. For text responses you need to use "w" - plain write mode. For binary responses you need to use "wb" - binary write mode.
How do you create a request object in Python?
r = requests.get(url = URL, params = PARAMS) Here we create a response object 'r' which will store the request-response. We use requests. ... .
data = r.json() Now, in order to retrieve the data from the response object, we need to convert the raw response content into a JSON type data structure..
What is a response object?
The Response Object is used to send a response to the client request from a server. It has many predefined methods, properties, and collections. It has some methods, properties, and collections. Properties. Buffer: It defines that whether the out page would be buffered or not.