Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example of mocking requests calls
#!/usr/bin/env python
"""
mocking requests calls
"""
import mock
import unittest
import requests
from requests.exceptions import HTTPError
def google_query(query):
"""
trivial function that does a GET request
against google, checks the status of the
result and returns the raw content
"""
url = "https://www.google.com"
params = {'q': query}
resp = requests.get(url, params=params)
resp.raise_for_status()
return resp.content
class TestRequestsCall(unittest.TestCase):
"""
example text that mocks requests.get and
returns a mock Response object
"""
def _mock_response(
self,
status=200,
content="CONTENT",
json_data=None,
raise_for_status=None):
"""
since we typically test a bunch of different
requests calls for a service, we are going to do
a lot of mock responses, so its usually a good idea
to have a helper function that builds these things
"""
mock_resp = mock.Mock()
# mock raise_for_status call w/optional error
mock_resp.raise_for_status = mock.Mock()
if raise_for_status:
mock_resp.raise_for_status.side_effect = raise_for_status
# set status code and content
mock_resp.status_code = status
mock_resp.content = content
# add json data if provided
if json_data:
mock_resp.json = mock.Mock(
return_value=json_data
)
return mock_resp
@mock.patch('requests.get')
def test_google_query(self, mock_get):
"""test google query method"""
mock_resp = self._mock_response(content="ELEPHANTS")
mock_get.return_value = mock_resp
result = google_query('elephants')
self.assertEqual(result, 'ELEPHANTS')
self.assertTrue(mock_resp.raise_for_status.called)
@mock.patch('requests.get')
def test_failed_query(self, mock_get):
"""test case where google is down"""
mock_resp = self._mock_response(status=500, raise_for_status=HTTPError("google is down"))
mock_get.return_value = mock_resp
self.assertRaises(HTTPError, google_query, 'elephants')
if __name__ == '__main__':
unittest.main()
@imrek

This comment has been minimized.

Copy link

imrek commented May 1, 2017

Thank you for this example.

@curious-codr

This comment has been minimized.

Copy link

curious-codr commented Sep 12, 2017

How to mock request object with json keyvalue pairs

@lcantonelli

This comment has been minimized.

Copy link

lcantonelli commented Mar 29, 2018

Great

@malhotra18

This comment has been minimized.

Copy link

malhotra18 commented Apr 4, 2018

Awsome example.. Thanks :)

@4lberto

This comment has been minimized.

Copy link

4lberto commented Apr 25, 2018

Thank you!!! very clear and simple

@zerogvt

This comment has been minimized.

Copy link

zerogvt commented Jul 23, 2018

👍

@Michael98Liu

This comment has been minimized.

Copy link

Michael98Liu commented Aug 1, 2018

Hi, thanks for the gist. I have a question about the test_fail_query function. Why it doesn't work if I change self.assertRaises(HTTPError, google_query, 'elephants') to self.assertRaises(HTTPError, mock_get)? Since the status code is 500. Shouldn't HTTPError be raised?

@evansde77

This comment has been minimized.

Copy link
Owner Author

evansde77 commented Sep 12, 2018

Hi, thanks for the gist. I have a question about the test_fail_query function. Why it doesn't work if I change self.assertRaises(HTTPError, google_query, 'elephants') to self.assertRaises(HTTPError, mock_get)? Since the status code is 500. Shouldn't HTTPError be raised?

mock_get is just the call to request get that returns a response object, that response's raise_for_status method is what triggers the HTTPError, so the equivalent behaviour would be something like this:

    @mock.patch('requests.get')
    def test_failed_query(self, mock_get):
        """test case where google is down"""
        mock_resp = self._mock_response(status=500, raise_for_status=HTTPError("google is down"))
        mock_get.return_value = mock_resp
        resp = mock_get()
        self.assertRaises(HTTPError, resp.raise_for_status, 'elephants')

Hope that helps!

@saimkhan92

This comment has been minimized.

Copy link

saimkhan92 commented Oct 4, 2018

Great example. I wanted to know what difference would it make if we get rid of line 46 in the helper function. Will the following code not produce the same end result?


def _mock_response(
            self,
            status=200,
            content="CONTENT",
            json_data=None,
            raise_for_status=None):
        """
        since we typically test a bunch of different
        requests calls for a service, we are going to do
        a lot of mock responses, so its usually a good idea
        to have a helper function that builds these things
        """
        mock_resp = mock.Mock()
        # mock raise_for_status call w/optional error
        if raise_for_status:
            mock_resp.raise_for_status.side_effect = raise_for_status
        # set status code and content
        mock_resp.status_code = status
        mock_resp.content = content
        # add json data if provided
        if json_data:
            mock_resp.json = mock.Mock(
                return_value=json_data
            )
        return mock_resp

Thanks.

@sthota18

This comment has been minimized.

Copy link

sthota18 commented Jan 30, 2020

Thank you so much for this example.

@MaxIakovliev

This comment has been minimized.

Copy link

MaxIakovliev commented May 26, 2020

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.