如何在不使用freeze_time库的情况下用pytest模拟datetime.now()?
正确模拟datetime.now()的方法
你的问题主要出在两个地方:
- 返回的
date(2011,11,18)是date类型,但datetime.now()返回的是datetime对象,类型不匹配会导致后续时间计算出错 - 需确认patch的路径是否和代码的导入逻辑匹配
修复现有patch写法
先把返回值改成datetime对象,同时确保patch路径正确。假设你的测试文件是直接从app导入foo:
测试代码示例:
from datetime import datetime from app import foo def test_foo(mocker): # 构造指定的datetime对象(需包含时间部分,也可用datetime.combine结合date对象生成) mock_now = datetime(2011, 11, 18, 12, 0, 0) # patch app模块内的datetime.now方法 mocker.patch("app.datetime.now", return_value=mock_now) result = foo() # 预期结果为当前时间往前推15天:2011-11-03 12:00:00 assert result == datetime(2011, 11, 3, 12, 0, 0)
更易维护的替代方案
如果不想依赖patch datetime的路径,建议把获取当前时间的逻辑抽成独立函数,测试起来更灵活:
修改app.py:
from datetime import datetime, timedelta def get_now(): return datetime.now() def foo(): now = get_now() return now - timedelta(days=15)
测试时直接patch这个get_now函数:
from datetime import datetime from app import foo def test_foo(mocker): mock_now = datetime(2011, 11, 18, 12, 0, 0) mocker.patch("app.get_now", return_value=mock_now) result = foo() assert result == datetime(2011, 11, 3, 12, 0, 0)
这种方式逻辑更清晰,后续如果要调整时间获取规则(比如改用UTC时间),也无需修改测试代码。
内容的提问来源于stack exchange,提问作者Mateusz
相关产品推荐
相关产品推荐

