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.
pip install requests
Python code
20 linesimport 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
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
- Use `unittest.mock.patch` to mock `requests.get` directly if you can't change the function signature.
- 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
More from Errors & debugging
- Catch RecursionError and Fail Gracefully in Python easy
- Catch ValueError and print friendly message in Python easy
- Collect Multiple Validation Errors in Python Before Raising medium
- Handle ValueError and ZeroDivisionError in Python with try except easy
- How to Add a Correlation ID to Logging Records in Python medium
- How to Assert Preconditions with Descriptive Messages in Python easy
Keep learning
Related tutorials and quizzes for this topic.