Python mock requests.post to throw exception
Mock the requests.post
function, and on the mock set the side_effect
attribute to the desired exception:
@patch('requests.post')
def test_request_post_exception(self, post_mock):
post_mock.side_effect = requests.exceptions.ConnectionError()
# run your test, code calling `requests.post()` will trigger the exception.
From the linked documentation:
This can either be a function to be called when the mock is called, an iterable or an exception (class or instance) to be raised.
[...]
An example of a mock that raises an exception (to test exception handling of an API):
>>> mock = Mock() >>> mock.side_effect = Exception('Boom!') >>> mock() Traceback (most recent call last): ... Exception: Boom!
(Bold emphasis mine).
This is also covered in the Quick Guide section:
side_effect
allows you to perform side effects, including raising an exception when a mock is called:>>> mock = Mock(side_effect=KeyError('foo')) >>> mock() Traceback (most recent call last): ... KeyError: 'foo'
Related videos on Youtube
camelBack
Updated on September 16, 2022Comments
-
camelBack over 1 year
Using Python 3.5, requests==2.18.4, Flask==0.12.2, urllib3==1.22
I have a method
some_method
in my mainserver.py
file, that is supposed to make aPOST
to some url with some data:def some_method(url, data): ... error = None try: response = requests.post(url, json=data) except requests.exceptions.ConnectionError as e: ... app.logger.error(...) response = None error = str(e) return error, response
The server file defines:
app = Flask(__name__)
, andsome_method
is called from@app.route(... methods=['PATCH'])
.
If this method throws an error, the route will eventually return a500
.Tests are run from a test file importing the app with
import server
andapp = server.app
, usingunittest
, and importingmock.patch
.I am able to test the overall app behavior, with a test that shows that the app route behave as expected when the method returns an error and seeing that the route terminates at the right spot:
class ServerTestCase(unittest.TestCase): ... @patch('server.some_method') def test_route_response_status_500_when_throws(self, mock_response): mock_response.return_value = 'some_error_string', None response = self.app.patch(some_url, some_data, content_type='application/json') self.assertEqual(response.status_code, 500)
However, I would really like to have another test to test
some_method
in isolation:- Mock
requests.post
to throwrequests.exceptions.ConnectionError
- Show that the method logs an error (I know I can mock my
app.logger
and assert that it logged during the execution)
-
Martijn PietersSo where did you get stuck? You can mock
requests.post
just fine, and you can have a mock raise exceptions by setting theside_effects
attribute.
- Mock
-
camelBack about 6 yearsThank you! I was doing what you mentioned in your response, but I had a few errors: 1.
requests.exceptions.ConnectionError
->requests.exceptions.ConnectionError()
2. Was trying many variations ofpatch
, also object but then changed to ->@patch('requests.post')