小能豆

我无法datetime.utcnow正确修补

python

我无法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 :/

当我运行时pytestpet.ts不会分配修补的时间戳。相反,它正在获取当前日期和时间。我想知道我的设置中可能有什么问题/缺失。有人有想法吗?

我正在使用以下工具:

Python   3.9.8
pydantic 1.9.0
pytest   6.25

阅读 170

收藏
2023-10-09

共1个答案

小能豆

问题出在你的测试代码中,当你使用 @patch("my_module.datetime") 修补 datetime 模块时,它实际上没有影响到 my_module 中的 datetime 引用,因为 my_module 已经导入了 datetime 模块,并且使用了自己的引用。

为了解决这个问题,你可以尝试修改测试代码,以便直接修补 my_module 中的 datetime 引用。你可以使用 patchtarget 参数来指定要修补的对象,如下所示:

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 字段始终包含你提供的时间戳,而不会获取当前日期和时间。

2023-10-09