{"id":438,"date":"2024-01-29T11:22:01","date_gmt":"2024-01-29T11:22:01","guid":{"rendered":"https:\/\/learnpython.elegantwallp.com\/?p=438"},"modified":"2024-01-29T11:22:02","modified_gmt":"2024-01-29T11:22:02","slug":"python-mock-requests","status":"publish","type":"post","link":"https:\/\/learnpython.elegantwallp.com\/2024\/01\/29\/python-mock-requests\/","title":{"rendered":"Python Mock Requests"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: In this tutorial, you\u2019ll learn how to mock the\u00a0<code>requests<\/code>\u00a0module in Python to test an API call using the\u00a0unittest\u00a0module.<\/p>\n\n\n\n<p>The&nbsp;<code>requests<\/code>&nbsp;module is an HTTP library that allows you to send HTTP requests easily. Typically, you use the&nbsp;<code>requests<\/code>&nbsp;module to call an API from a remote server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The scenario<\/h2>\n\n\n\n<p>For the demo purposes, we\u2019ll use a public API provided by\u00a0jsonplaceholder.typicode.com:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>https:\/\/jsonplaceholder.typicode.com\/<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>To make an API call, you\u2019ll use the\u00a0<code>requests<\/code>\u00a0method to send an HTTP GET method to the following end-point:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>https:\/\/jsonplaceholder.typicode.com\/albums\/1<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>It\u2019ll return JSON data in the following format:<\/p>\n\n\n\n<p><code>{ \"userId\": 1, \"id\": 1, \"title\": \"quidem molestiae enim\" }<\/code><small>Code language: Python (python)<\/small><\/p>\n\n\n\n<p>Since the\u00a0<code>requests<\/code>\u00a0module is not a built-in module, you need to install it by running the following pip command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>pip install requests<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Making an API call using the requests module<\/h2>\n\n\n\n<p>The following defines a new module called\u00a0<code>album.py<\/code>\u00a0with a function\u00a0<code>find_album_by_id()<\/code>\u00a0that returns an album by an id:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import requests def find_album_by_id(id): url = f'https:\/\/jsonplaceholder.typicode.com\/albums\/{id}' response = requests.get(url) if response.status_code == 200: return response.json()&#91;'title'] else: return None<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, format the API end-point that includes the id parameter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>url = f'https:\/\/jsonplaceholder.typicode.com\/albums\/{id}'<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Second, call the\u00a0<code>get()<\/code>\u00a0function of the requests module to get a\u00a0<code>Response<\/code>\u00a0object:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>response = requests.get(url)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Third, call the\u00a0<code>json()<\/code>\u00a0method of the response object if the API call succeeds:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>if response.status_code == 200: return response.json()&#91;'title'] else: return None<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>The&nbsp;<code>response.json()<\/code>&nbsp;returns a dictionary that represents the JSON data.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Creating a test module<\/h2>\n\n\n\n<p>We\u2019ll create a\u00a0<code>test_album.py<\/code>\u00a0test module that tests the functions in the\u00a0<code>album.py<\/code>\u00a0module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import unittest from album import find_album_by_id class TestAlbum(unittest.TestCase): pass<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Mocking the requests module<\/h3>\n\n\n\n<p>The&nbsp;<code>find_album_by_id()<\/code>&nbsp;function has two dependencies:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The&nbsp;<code>get()<\/code>&nbsp;method of the&nbsp;<code>requests<\/code>&nbsp;module<\/li>\n\n\n\n<li>The&nbsp;<code>Response<\/code>&nbsp;object returned by the&nbsp;<code>get()<\/code>&nbsp;function.<\/li>\n<\/ul>\n\n\n\n<p>So to test the&nbsp;<code>find_album_by_id()<\/code>&nbsp;function, you need to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First, mock the requests module and call the&nbsp;<code>get()<\/code>&nbsp;function (<code>mock_requests<\/code>)<\/li>\n\n\n\n<li>Second, mock the returned response object.<\/li>\n<\/ul>\n\n\n\n<p>In other words, the mock_requests.<code>get()<\/code>&nbsp;returns a mock response object.<\/p>\n\n\n\n<p>To mock the requests module, you can use the&nbsp;<code>patch()<\/code>&nbsp;function. Suppose that the&nbsp;<code>mock_requests<\/code>&nbsp;is a mock of the&nbsp;<code>requests<\/code>&nbsp;module.<\/p>\n\n\n\n<p>The&nbsp;<code>mock_requests.get()<\/code>&nbsp;should return a mock for the response. To mock the response, you can use the&nbsp;<code>MagicMock<\/code>&nbsp;class of the&nbsp;<code>unittest.mock<\/code>&nbsp;module.<\/p>\n\n\n\n<p>The following shows how to test the\u00a0<code>find_album_by_id()<\/code>\u00a0using the\u00a0<code>test_find_album_by_id_success()<\/code>\u00a0test method:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import unittest from unittest.mock import MagicMock, patch from album import find_album_by_id class TestAlbum(unittest.TestCase): @patch('album.requests') def test_find_album_by_id_success(self, mock_requests): <em># mock the response<\/em> mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = { 'userId': 1, 'id': 1, 'title': 'hello', } <em># specify the return value of the get() method<\/em> mock_requests.get.return_value = mock_response <em># call the find_album_by_id and test if the title is 'hello'<\/em> self.assertEqual(find_album_by_id(1), 'hello')<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, patch the\u00a0<code>requests<\/code>\u00a0module as the\u00a0<code>mock_requests<\/code>\u00a0object:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>@patch('album.requests') def test_find_album_by_id_success(self, mock_requests): <em># ...<\/em><\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Second, mock the response of the\u00a0<code>get()<\/code>\u00a0function using the\u00a0<code>MagicMock<\/code>\u00a0class. In this test method, we specify the status code 200 and\u00a0<code>return_value<\/code>\u00a0of the\u00a0<code>json()<\/code>\u00a0function as a hard-coded value:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = { 'userId': 1, 'id': 1, 'title': 'hello', }<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Third, use the mock_response as the return value of the\u00a0<code>get()<\/code>\u00a0function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code> mock_requests.get.return_value = mock_response<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Finally, test if the title of the album is equal to the one that we specified in the\u00a0<code>return_value<\/code>\u00a0of the\u00a0<code>mock_response<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>self.assertEqual(find_album_by_id(1), 'hello')<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Run the test:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>python -m unittest -v<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>test_find_album_by_id_success (test_album.TestAlbum) ... ok ---------------------------------------------------------------------- Ran 1 test in 0.001s OK<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>By using the same technique, you can also test the\u00a0<code>find_album_by_id()<\/code>\u00a0function in the failed case:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>import unittest from unittest.mock import MagicMock, patch from album import find_album_by_id class TestAlbum(unittest.TestCase): @patch('album.requests') def test_find_album_by_id_success(self, mock_requests): <em># mock the response<\/em> mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = { 'userId': 1, 'id': 1, 'title': 'hello', } <em># specify the return value of the get() method<\/em> mock_requests.get.return_value = mock_response <em># call the find_album_by_id and test if the title is 'hello'<\/em> self.assertEqual(find_album_by_id(1), 'hello') @patch('album.requests') def test_find_album_by_id_fail(self, mock_requests): mock_response = MagicMock() mock_response.status_code = 400 mock_requests.get.return_value = mock_response self.assertIsNone(find_album_by_id(1))<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>test_find_album_by_id_fail (test_album.TestAlbum) ... ok test_find_album_by_id_success (test_album.TestAlbum) ... ok ---------------------------------------------------------------------- Ran 2 tests in 0.002s OK<\/code><\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Summary: In this tutorial, you\u2019ll learn how to mock the\u00a0requests\u00a0module in Python to test an API call using the\u00a0unittest\u00a0module. The&nbsp;requests&nbsp;module is an HTTP library that allows you to send HTTP requests easily. Typically, you use the&nbsp;requests&nbsp;module to call an API from a remote server. The scenario For the demo purposes, we\u2019ll use a public API [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[43],"tags":[],"class_list":["post-438","post","type-post","status-publish","format-standard","hentry","category-3-python-unit-testing"],"_links":{"self":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/comments?post=438"}],"version-history":[{"count":1,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/438\/revisions"}],"predecessor-version":[{"id":439,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/438\/revisions\/439"}],"wp:attachment":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/media?parent=438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/categories?post=438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/tags?post=438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}