使用pytest-mock模拟datetime.datetime.now遇TypeError,如何解决?
解决无法Mock datetime.datetime.now的报错问题
报错原因
直接Patch全局的datetime.datetime.now会触发TypeError,因为datetime.datetime是Python内置的不可变类型,不允许修改其属性。更关键的是,你的测试代码违背了Mock的核心原则:要Mock被测试代码实际使用的引用,而非原始模块的全局引用。被测试函数func_to_mock在port_bt.module_to_mock模块内使用的是该模块导入的datetime实例,而非你测试文件里导入的全局datetime。
修正后的测试代码
调整Patch的目标路径,并修正断言逻辑:
# test_func_to_mock.py import datetime from pytest_mock import MockFixture import port_bt.module_to_mock def test_func_to_mock(mocker: MockFixture) -> None: # 目标改为被测试模块内的datetime.datetime.now mocked_now = mocker.patch( "port_bt.module_to_mock.datetime.datetime.now", return_value=datetime.datetime(2023, 1, 31, 0, 0, 0) ) # 断言返回值等于mock的预设值,而非mock对象本身 assert port_bt.module_to_mock.func_to_mock() == mocked_now.return_value
核心注意点
- Patch路径要精准:遵循"where it's used"规则,Mock的是被测试代码所在模块中导入的依赖,而非全局依赖。这里
func_to_mock调用的是port_bt.module_to_mock里的datetime.datetime.now,所以必须Patch这个路径。 - 断言对象要正确:
mocker.patch返回的是Mock实例,你需要断言的是它的return_value属性,而不是Mock对象本身。
内容的提问来源于stack exchange,提问作者Andi
相关产品推荐
相关产品推荐

