Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pytest raise test failing for requests.raise_for_status()

I've recently started using pytest, and even more recently started using mock for mocking the requests library. I have made a requests.Response object okay, and for a 200 status code it works fine. What I'm trying to do here, is to use raise_for_status() to check for a rate limit exceeded error, and test that it handles the exception with pytest.

I'm using the Mock side_effect option, which seems to fire the exception I'm hoping, but pytest doesn't seem to recognise this as having happened and fails the test.

Any thoughts? I'm sure it's something obvious I'm missing!

The code I have for the class is:

class APIClient:
    def get_records(self, url):
        try:
            r = requests.get(url)
            r.raise_for_status()
            return r.json()
        except requests.HTTPError as e:
            print("Handling the exception")

In the test class, I have got:

@pytest.fixture
def http_error_response(rate_limit_json):
    mock_response = mock.Mock()
    mock_response.json.return_value = rate_limit_json
    mock_response.status_code = 429

    mock_response.raise_for_status.side_effect = requests.exceptions.HTTPError

    return mock_response


class TestRecovery(object):

    @mock.patch('requests.get')
    def test_throws_exception_for_rate_limit_error\
    (self, mock_get, api_query_object, http_error_response):

        mock_get.return_value = http_error_response
        print(http_error_response.raise_for_status.side_effect)

        url = api_query_object.get_next_url()

        with pytest.raises(requests.exceptions.HTTPError):
            api_query_object.get_records(url)

The output I get is:

    with pytest.raises(requests.exceptions.HTTPError):
>           api_query_object.get_records(url)
E           Failed: DID NOT RAISE

---------------------- Captured stdout call ---------------------- 
<class 'requests.exceptions.HTTPError'>
Handling the exception
like image 593
huwf Avatar asked Feb 20 '16 12:02

huwf


1 Answers

You are instructing pytest to expect an exception that should be raised in APIClient.get_records but inside that method definition you are already capturing the exception and just doing a print.

The exception is actually happening and it proved by seeing the result of your print in the console output.

Instead of that you should either check with the mock that the method raise_for_status was called.

like image 196
lucrib Avatar answered Nov 10 '22 08:11

lucrib