Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow raw parameter to accept callable like body elements
Browse files Browse the repository at this point in the history
ramast authored and jamielennox committed Jan 22, 2024
1 parent c06f124 commit 8eecfa2
Showing 6 changed files with 42 additions and 11 deletions.
3 changes: 3 additions & 0 deletions doc/source/response.rst
Original file line number Diff line number Diff line change
@@ -70,6 +70,9 @@ Dynamic Response
================

A callback can be provided in place of any of the body elements.
raw attribute also accepts callable that returns HTTPResponse.
The HTTPResponse should have `preload_content=False` or it may not work properly.

Callbacks must be a function in the form of

.. code:: python
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
features:
- |
When using dynamic responses, you can now use a callback function for the
raw HTTPResponse object. This aligns it with all the other parameters that
can be mocked.
2 changes: 1 addition & 1 deletion requests_mock/adapter.pyi
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ class Adapter(BaseAdapter, _RequestHistoryTracker):
text: Union[str, Callback[str]] = ...,
content: Union[bytes, Callback[bytes]] = ...,
body: Union[IOBase, Callback[IOBase]] = ...,
raw: HTTPResponse = ...,
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
exc: Union[Exception, Type[Exception]] = ...,
additional_matcher: AdditionalMatcher = ...,
**kwargs: Any
18 changes: 9 additions & 9 deletions requests_mock/mocker.pyi
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@ class MockerCore:
text: Union[str, Callback[str]] = ...,
content: Union[bytes, Callback[bytes]] = ...,
body: Union[IOBase, Callback[IOBase]] = ...,
raw: HTTPResponse = ...,
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
exc: Union[Exception, Type[Exception]] = ...,
additional_matcher: AdditionalMatcher = ...,
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -77,7 +77,7 @@ class MockerCore:
text: Union[str, Callback[str]] = ...,
content: Union[bytes, Callback[bytes]] = ...,
body: Union[IOBase, Callback[IOBase]] = ...,
raw: HTTPResponse = ...,
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
exc: Union[Exception, Type[Exception]] = ...,
additional_matcher: AdditionalMatcher = ...,
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -99,7 +99,7 @@ class MockerCore:
text: Union[str, Callback[str]] = ...,
content: Union[bytes, Callback[bytes]] = ...,
body: Union[IOBase, Callback[IOBase]] = ...,
raw: HTTPResponse = ...,
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
exc: Union[Exception, Type[Exception]] = ...,
additional_matcher: AdditionalMatcher = ...,
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -121,7 +121,7 @@ class MockerCore:
text: Union[str, Callback[str]] = ...,
content: Union[bytes, Callback[bytes]] = ...,
body: Union[IOBase, Callback[IOBase]] = ...,
raw: HTTPResponse = ...,
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
exc: Union[Exception, Type[Exception]] = ...,
additional_matcher: AdditionalMatcher = ...,
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -143,7 +143,7 @@ class MockerCore:
text: Union[str, Callback[str]] = ...,
content: Union[bytes, Callback[bytes]] = ...,
body: Union[IOBase, Callback[IOBase]] = ...,
raw: HTTPResponse = ...,
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
exc: Union[Exception, Type[Exception]] = ...,
additional_matcher: AdditionalMatcher = ...,
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -165,7 +165,7 @@ class MockerCore:
text: Union[str, Callback[str]] = ...,
content: Union[bytes, Callback[bytes]] = ...,
body: Union[IOBase, Callback[IOBase]] = ...,
raw: HTTPResponse = ...,
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
exc: Union[Exception, Type[Exception]] = ...,
additional_matcher: AdditionalMatcher = ...,
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -187,7 +187,7 @@ class MockerCore:
text: Union[str, Callback[str]] = ...,
content: Union[bytes, Callback[bytes]] = ...,
body: Union[IOBase, Callback[IOBase]] = ...,
raw: HTTPResponse = ...,
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
exc: Union[Exception, Type[Exception]] = ...,
additional_matcher: AdditionalMatcher = ...,
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -209,7 +209,7 @@ class MockerCore:
text: Union[str, Callback[str]] = ...,
content: Union[bytes, Callback[bytes]] = ...,
body: Union[IOBase, Callback[IOBase]] = ...,
raw: HTTPResponse = ...,
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
exc: Union[Exception, Type[Exception]] = ...,
additional_matcher: AdditionalMatcher = ...,
json_encoder: Optional[Type[JSONEncoder]] = ...,
@@ -231,7 +231,7 @@ class MockerCore:
text: Union[str, Callback[str]] = ...,
content: Union[bytes, Callback[bytes]] = ...,
body: Union[IOBase, Callback[IOBase]] = ...,
raw: HTTPResponse = ...,
raw: Union[HTTPResponse, Callback[HTTPResponse]] = ...,
exc: Union[Exception, Type[Exception]] = ...,
additional_matcher: AdditionalMatcher = ...,
json_encoder: Optional[Type[JSONEncoder]] = ...,
2 changes: 1 addition & 1 deletion requests_mock/response.py
Original file line number Diff line number Diff line change
@@ -273,7 +273,7 @@ def _call(f, *args, **kwargs):
text=_call(self._params.get('text')),
content=_call(self._params.get('content')),
body=_call(self._params.get('body')),
raw=self._params.get('raw'),
raw=_call(self._params.get('raw')),
json_encoder=self._params.get('json_encoder'),
status_code=context.status_code,
reason=context.reason,
22 changes: 22 additions & 0 deletions tests/test_adapter.py
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
import requests
import six
from six.moves.urllib import parse as urlparse
from urllib3 import HTTPResponse

import requests_mock
from . import base
@@ -120,6 +121,27 @@ def _text_cb(request, context):
self.assertHeaders(resp)
self.assertLastRequest()

def test_raw_callback(self):
status_code = 401
data = 'testdata'

def _raw_cb(request, context):
return HTTPResponse(
status=status_code,
headers=self.headers,
body=six.BytesIO(six.b(data)),
preload_content=False,
reason=six.moves.http_client.responses.get(status_code),
)

self.adapter.register_uri('GET', self.url, raw=_raw_cb)
resp = self.session.get(self.url)
self.assertEqual(status_code, resp.status_code)
self.assertEqual(six.u(data), resp.text)
self.assertEqual(six.b(data), resp.content)
self.assertHeaders(resp)
self.assertLastRequest()

def test_json(self):
json_data = {'hello': 'world'}
self.adapter.register_uri('GET',

0 comments on commit 8eecfa2

Please sign in to comment.