How to Mock a Timeout per Dependency Call in Python

This code demonstrates how to simulate and test per-call timeouts for external dependencies using Python's unittest.mock and a simple timing wrapper.

Medium Python 3.9+ Aug 9, 2026 System design patterns 14 views 0 copies

Python code

29 lines
Python 3.9+
```python
import time
from unittest.mock import Mock, patch

def call_dependency(dependency, timeout):
    start = time.time()
    result = dependency.call()
    elapsed = time.time() - start
    if elapsed > timeout:
        raise TimeoutError(f"Dependency call took {elapsed:.2f}s, exceeding timeout {timeout}s")
    return result

if __name__ == "__main__":
    # Mock that simulates a slow dependency
    slow_dependency = Mock()
    slow_dependency.call.side_effect = lambda: time.sleep(0.2) or "data"
    
    # Mock that responds quickly
    fast_dependency = Mock()
    fast_dependency.call.return_value = "result"
    
    # Test with a short timeout
    try:
        call_dependency(slow_dependency, timeout=0.1)
    except TimeoutError as e:
        print(f"Caught: {e}")
    
    # Test with a generous timeout
    print(f"Fast dependency result: {call_dependency(fast_dependency, timeout=0.1)}")

Output

stdout
Caught: Dependency call took 0.20s, exceeding timeout 0.1s
Fast dependency result: result

How it works

This example uses unittest.mock.Mock to create fake dependencies with controllable behavior via side_effect and return_value. The call_dependency function measures the wall-clock time of the dependency call using time.time() and raises a TimeoutError if the elapsed time exceeds the specified timeout. The slow mock uses a lambda with time.sleep to simulate latency, while the fast mock returns instantly. This pattern lets you test timeout logic without real network or I/O operations.

Common mistakes

  • Forgetting that `side_effect` is callable and using it as a value instead of a function
  • Measuring time before the call but not accounting for system clock changes or other overhead
  • Not mocking `time.time` itself when you need deterministic tests

Variations

  1. Use `unittest.mock.patch('time.time')` to freeze time for deterministic timeout testing
  2. Implement a retry wrapper that catches TimeoutError and retries with backoff

Real-world use cases

  • Testing circuit breaker logic in microservices when a downstream API call exceeds its budget.
  • Verifying that a background job fails fast when an external data source is unresponsive.
  • Writing unit tests for a service that enforces a per-request timeout against a legacy database client.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from System design patterns

Related tutorials and quizzes for this topic.