我无法datetime.utcnow正确修补,我想知道可能出了什么问题。下面的代码说明了这个想法:
datetime.utcnow
# In a file called 'my_module.py' from datetime import datetime from pydantic import BaseModel, Field class Pet(BaseModel): ts: datetime = Field(default_factory=datetime.utcnow)
对应的测试代码为:
from datetime import datetime from unittest.mock import patch from my_module import Pet @patch("my_module.datetime") def test_pet(mocked): timestamp = datetime(2000, 10, 10, 21, 50) mocked.utcnow.return_value = timestamp pet = Pet() assert pet.ts == timestamp # pet.ts is getting current date and time :/
当我运行时pytest,pet.ts不会分配修补的时间戳。相反,它正在获取当前日期和时间。我想知道我的设置中可能有什么问题/缺失。有人有想法吗?
pytest
pet.ts
我正在使用以下工具:
Python 3.9.8 pydantic 1.9.0 pytest 6.25
问题出在你的测试代码中,当你使用 @patch("my_module.datetime") 修补 datetime 模块时,它实际上没有影响到 my_module 中的 datetime 引用,因为 my_module 已经导入了 datetime 模块,并且使用了自己的引用。
@patch("my_module.datetime")
datetime
my_module
为了解决这个问题,你可以尝试修改测试代码,以便直接修补 my_module 中的 datetime 引用。你可以使用 patch 的 target 参数来指定要修补的对象,如下所示:
patch
target
from datetime import datetime from unittest.mock import patch from my_module import Pet def test_pet(): timestamp = datetime(2000, 10, 10, 21, 50) with patch("my_module.datetime", lambda: timestamp): pet = Pet() assert pet.ts == timestamp
在这个示例中,我们使用 patch 修补了 my_module 中的 datetime 引用,将其替换为一个 lambda 函数,该函数返回你所期望的时间戳。这样,你就可以确保 Pet 类的 ts 字段始终包含你提供的时间戳,而不会获取当前日期和时间。
Pet
ts