Mocking and Patching with unittest.mock
flowchart TD
A["svc.py defines now()"] --> B["app.py does: from svc import now"]
B --> C["app.now and svc.now both point at the same function"]
D["patch('svc.now')"] --> E["replaces the name in svc"]
E --> F["app.now still points at the ORIGINAL"]
F --> G["greet() returns 'hello REAL' -- the mock did nothing"]
H["patch('app.now')"] --> I["replaces the name app actually looks up"]
I --> J["greet() returns 'hello FAKE' -- the mock works"]
Why mock?
Section titled “Why mock?”You mock when a dependency is:
- slow
- flaky
- external (network, API)
- expensive to set up
Example: patch a function call
Section titled “Example: patch a function call”import requests
def fetch_status(url: str) -> int:
return requests.get(url, timeout=10).status_codefrom unittest.mock import patch
import service
def test_fetch_status_mocked():
with patch("service.requests.get") as get:
get.return_value.status_code = 200
assert service.fetch_status("https://example.com") == 200Using autospec
Section titled “Using autospec”autospec=True helps match real signatures.
from unittest.mock import patch
def sample(a, b):
return a + b
with patch("__main__.sample", autospec=True) as fn:
fn.return_value = 10
assert sample(1, 2) == 10- mock at the import location used by the code under test
- keep mocks minimal; prefer real unit logic
pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading