Using Python 3.5, requests==2.18.4, Flask==0.12.2, urllib3==1.22
I have a method some_method in my main server.py file, that is supposed to make a POST 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__), and some_method is called from @app.route(... methods=['PATCH']).
If this method throws an error, the route will eventually return a 500.
Tests are run from a test file importing the app with import server and app = server.app, using unittest, and importing mock.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:
requests.post to throw requests.exceptions.ConnectionError
app.logger and assert that it logged during the execution)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_effectallows 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'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With