Python unittesting request.get with mocking, not raising specific exception
<p>I have a simple function that sends a get request to an API, and I want to be able to write a Unit test to assert that the scriprt prints an error and then exits if the request returns an exception.</p>

<pre><code>def fetch_members(self):
    try:
        r = requests.get(api_url, auth=('user', api_key))
    except requests.exceptions.HTTPError as error:
        print(error)
        sys.exit(1)
</code></pre>

<p>I've tried the following test but the HTTPError is never raised</p>

<pre><code>import requests
from unittest.mock import patch

@patch('sys.exit')
@patch('sys.stdout', new_callable=StringIO)
@patch('requests.get')
def test_fetch_members_with_bad_request(self, mock_get, mock_stdout,
                                        mock_exit):
    response = requests.Response()
    response.status_code = 400  # Bad reqeust
    mock_get.return_value = response
    mock_get.side_effect = requests.exceptions.HTTPError
    with self.assertRaises(requests.exceptions.HTTPError):
        fetch_members()
        mock_exit.assert_called_once_with(1)
        self.assertIsNotNone(mock_stdout.getvalue())
</code></pre>

<p>How would I go about correctly patching requests.get to always raise some sort of error?</p>

<p>Your function catches and handles the exception:</p>

<pre><code>except requests.exceptions.HTTPError as error:
</code></pre>

<p>This means it'll <em>never</em> propagate further, so your <code>assertRaises()</code> fails. Just assert that <code>sys.exit()</code> has been called, that's enough.</p>

<p>There is also no point in setting a return value; the call raises an exception instead. The following should suffice:</p>

<pre><code>@patch('sys.exit')
@patch('sys.stdout', new_callable=StringIO)
@patch('requests.get')
def test_fetch_members_with_bad_request(self, mock_get, mock_stdout,
                                        mock_exit):
    mock_get.side_effect = requests.exceptions.HTTPError
    fetch_members()
    mock_exit.assert_called_once_with(1)
    self.assertIsNotNone(mock_stdout.getvalue())
</code></pre>

python unit-testing