Mocking external API calls

RoadmapsPython

Overview

**Memorizable line:** Mocking an API means replacing a slow internet request with a fake, instant response. When we write tests, we do not want to actually call outside APIs like Google or Stripe. It is slow, costs money, and requires internet. Instead, we `mock` the API call. Here is a function that gets a user profile from an API. ```python import requests def get_profile(user_id): response = requests.get(f'http://api.com/{user_id}') return response.json() ``` We can use `patch` to mock `requests.get`. We give it a fake response that acts like the real one. ```python from unittest.mock import patch, Mock @patch('__main__.requests.get') def test_profile(mock_get): fake_response = Mock() fake_response.json.return_value = {'name': 'Rahul'} mock_get.return_value = fake_response assert get_profile(1)['name'] == 'Rahul' ``` **Analogy:** Think of a fire drill. You do not start a real fire to test the alarm. You use a smoke machine to fake the fire. Mocking is the smoke machine for your code.

It keeps tests fast, free, and reliable. Your tests will pass even without internet.

Where used: pytest, unittest

Why learn this

Code walkthrough

from unittest.mock import Mock

def get_data(api_call):
    resp = api_call()
    return resp.json()

fake_api = Mock()
fake_api.return_value.json.return_value = 'data'
print(get_data(fake_api))

Focus: fake_api.return_value.json.return_value = 'data'

Aha moment

from unittest.mock import Mock
mock_obj = Mock()
mock_obj.some_method.return_value = 42
print(mock_obj.some_method())

Prediction: What does this print?

Common guess: An error, because some_method does not exist.

A Mock object magically accepts any method call you invent and returns what you tell it to.

Common mistakes

Recall questions

Understanding checks

What prints, and why?

ok

The fake response was set up so its `.json()` method returns a dictionary with 'status': 'ok'.

Where is the bug?

fake_resp.return_value is set, but it should be fake_resp.json.return_value.

The real code calls `.json()`, so we must mock the return value of the `json` method, not the response object itself.

Practice tasks

Mock a response

Given this working code, change `fake_resp.json.return_value` so that the printed name is 'Amit'.

Challenge

Create a fake response

Create a `Mock` object called `response`. Set its `status_code` attribute to `200` and make its `.json()` method return `['apple']`.

Continue learning

Previous: patch as decorator and context manager

Return to Python Roadmap