AssertionError:assert datetime.datetime(2025, 1, 15, 10, 30) == datetime.datetime(2024, 6, 1, 0, 0) # 预期 freeze_time('2024-06-01') 会生效
AssertionError: assert datetime.datetime(2025, 1, 15, 10, 30) == datetime.datetime(2024, 6, 1, 0, 0) # expected freeze_time('2024-06-01') to apply
ID: python/pytest-freezegun-time-not-frozen
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| 1.5 | active | — | — | — |
根因分析
被测代码在 freeze_time 修补之前导入了 datetime 或 time 函数,或者使用了 freezegun 无法拦截的 C 扩展时钟(例如通过 numpy 的 time.monotonic_ns)。当模块执行 'from datetime import datetime' 时也常见。
English
The code under test imported datetime or time functions before freeze_time patched them, or uses a C-extension clock (e.g., time.monotonic_ns via numpy) that freezegun cannot intercept. Also common when the module does 'from datetime import datetime' and freezegun patches the class attribute incorrectly.
解决方案
-
90% 成功率
from freezegun import freeze_time @freeze_time('2024-06-01') def test_expiry(): # myapp/utils.py does: from datetime import datetime # freezegun patches datetime.datetime, so this works assert is_expired(datetime(2024, 5, 31)) -
95% 成功率
def is_expired(now=None): now = now or datetime.now(timezone.utc) return now > EXPIRY def test_expiry(): assert is_expired(now=datetime(2024, 5, 31, tzinfo=timezone.utc))
无效尝试
常见但无效的做法:
-
85% 失败
Nested freezes raise or silently override; the innermost wins, but the outer reference was already captured.
-
90% 失败
Sleep does not retroactively patch already-imported names; the test still sees real time.