I feel reluctant about mocking types I don’t own, and prefer small, tailored abstractions instead:
from datetime import datetime, timedelta
def f(now = datetime.now):
timestamp = now()
future = timestamp + timedelta(seconds=1)
return timestamp.time() < future.time()
def mockdt():
return datetime(2024, 10, 3, 23, 59, 59)
assert f(mockdt)
Admittedly, this approach adds _some_ noise to the function signature. On the other hand, it feels more honest. It makes it unmistakably clear that this API relies on, and uses, some external state.
Also, this approach scales poorly with the number of dependencies, and that’s a good thing. If `f` were to also depend on a `db_connection` in addition to `datetime.now`, then this pattern automatically alerts the API designer that it might be time to redesign `f`.