How to Mock a Failing Dependency to Test Error Paths in Python

Inject a fake HTTP client that raises a connection error to test how code handles dependency failures without touching the network.

Easy Python 3.9+ Aug 9, 2026 Errors & debugging 17 views 0 copies

Requires third-party packages — install first
pip install requests

Python code

20 lines
Python 3.9+
import requests

def fetch_user(user_id):
    url = f"https://api.example.com/users/{user_id}"
    response = requests.get(url, timeout=5)
    response.raise_for_status()
    return response.json()

def get_user_name(user_id, http_client):
    try:
        user_data = http_client(user_id)
        return user_data["name"]
    except requests.exceptions.RequestException:
        return "Unknown"

if __name__ == "__main__":
    def failing_client(user_id):
        raise requests.exceptions.ConnectionError("Mock failure")

    print(get_user_name(42, failing_client))  # Output: Unknown

Output

stdout
Unknown

How it works

The get_user_name function accepts an http_client callable instead of importing requests directly, which makes it easy to swap in a mock. In the __main__ block, failing_client raises requests.exceptions.ConnectionError, simulating a network failure. The try/except block catches that exception and returns "Unknown" as a fallback. This pattern, known as dependency injection, keeps the function testable without mocking libraries or network calls.

Common mistakes

  • Forgetting to catch the specific exception type and catching broad `Exception` instead.
  • Mocking the wrong layer (e.g., patching `requests.get` inside the function instead of injecting a client).
  • Missing the `raise_for_status()` call in real code, so HTTP errors (404, 500) are not converted to exceptions.

Variations

  1. Use `unittest.mock.patch` to mock `requests.get` directly if you can't change the function signature.
  2. Use a library like `responses` or `requests-mock` to simulate HTTP responses and exceptions.

Real-world use cases

  • Unit testing an API client that must return a default value when the service is down.
  • Verifying that a retry logic triggers when a network call raises a timeout.
  • Testing a background job that degrades gracefully when a third-party API is unreachable.

Sponsored

Run locally

This sample needs third-party packages, so it cannot run in the browser IDE. Copy the code above, install the packages shown at the top, then run it in your own Python environment.

More from Errors & debugging

Related tutorials and quizzes for this topic.