Backend Development 9 min read

How to Mock External Services in pytest Using unittest.mock

This guide explains how to install pytest, create a module with a function that calls an external API, and use unittest.mock fixtures and helper functions to mock requests.get for both successful and failing responses, then run the tests with pytest.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
How to Mock External Services in pytest Using unittest.mock

When writing unit tests with pytest , you often need to mock external services or functions. The standard library module unittest.mock provides powerful mocking capabilities that integrate smoothly with pytest .

1. Install dependencies

Make sure pytest is installed (the unittest.mock module is included in the Python standard library).

pip install pytest

2. Create the module to be tested

Assume a file my_module.py with a function fetch_data that calls an external API.

# my_module.py
import requests

def fetch_data(url):
    """Fetch data from the given URL.
    Args:
        url (str): API endpoint URL.
    Returns:
        dict: JSON data returned by the API.
    Raises:
        requests.exceptions.HTTPError: If the HTTP request fails.
    """
    response = requests.get(url)
    response.raise_for_status()  # Raise if the request failed
    return response.json()

3. Create the test file

In test_my_module.py , import pytest , MagicMock , patch , and the function to test.

# test_my_module.py
import pytest
from unittest.mock import MagicMock, patch
from my_module import fetch_data

3.1 Define a fixture to set up the mock object

# Define a fixture to set up the mock object
@pytest.fixture
def mock_requests_get():
    """Use a pytest fixture to mock
requests.get
."""
    with patch('requests.get') as mock_get:
        yield mock_get

3.2 Encapsulate mock behavior

# Encapsulate mock behavior
def setup_mock_response(mock_get, status_code=200, json_data=None):
    """Configure the mock response.
    Args:
        mock_get (MagicMock): The mocked
requests.get
object.
        status_code (int): HTTP status code (default 200).
        json_data (dict): JSON payload to return (default None).
    """
    mock_response = MagicMock()
    mock_response.status_code = status_code
    if json_data is not None:
        mock_response.json.return_value = json_data
    if status_code >= 400:
        mock_response.raise_for_status.side_effect = requests.exceptions.HTTPError("Request failed")
    mock_get.return_value = mock_response

3.3 Write test cases

# Test case: successful request
def test_fetch_data_success(mock_requests_get):
    """Test
fetch_data
when the request succeeds."""
    setup_mock_response(mock_requests_get, status_code=200, json_data={"key": "value"})
    result = fetch_data("http://example.com/api/data")
    assert result == {"key": "value"}
    mock_requests_get.assert_called_once_with("http://example.com/api/data")

# Test case: failed request
def test_fetch_data_failure(mock_requests_get):
    """Test
fetch_data
when the request fails."""
    setup_mock_response(mock_requests_get, status_code=404)
    with pytest.raises(requests.exceptions.HTTPError):
        fetch_data("http://example.com/api/data")
    mock_requests_get.assert_called_once_with("http://example.com/api/data")

4. Run the tests

Execute the tests from the terminal:

pytest test_my_module.py

Explanation

Installation: pip install pytest installs pytest; unittest.mock is built‑in.

Module creation: fetch_data retrieves JSON from a URL and raises HTTPError on failure.

Test file: The fixture mock_requests_get patches requests.get .

Helper function: setup_mock_response configures status code and JSON payload for the mock.

Test cases: Verify correct behavior for both successful and error responses, and assert that requests.get is called with the expected URL.

BackendPythonunit testingMockingpytestunittest.mock
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.