【发布时间】:2019-08-27 09:27:09
【问题描述】:
我的 utils.py 中有以下功能,基本上计算从 1970 年到当前时间的秒数:
import datetime
def get_utc_timestamp():
d = datetime.datetime.utcnow()
epoch = datetime.datetime(1970, 1, 1)
t = (d - epoch).total_seconds()
return t
我想在该函数上运行一个测试用例,但它取决于时间,所以我寻找解决方案并在 SO link 上偶然发现了这个问题,我试图在我的 test_utils.py 中应用它:
import unittest
from utils import *
from unittest import mock
import datetime
class TestUtils(unittest.TestCase):
@mock.patch('utils.datetime.datetime')
def test_get_utc_timestamp(self, mock_dt):
mock_dt.utcnow = mock.Mock(return_value = datetime.datetime(2019, 8, 27, 8, 52, 12, 703618))
result = get_utc_timestamp()
self.assertEqual(result, 1566895932.703618)
if __name__ == '__main__':
unittest.main()
我在控制台中测试了它的结果:
d = datetime.datetime(2019, 8, 27, 8, 52, 12, 703618)
epoch = datetime.datetime(1970, 1, 1)
t = (d - epoch).total_seconds()
return t
它返回了
1566895932.703618
但是当我运行测试时,我得到了 AssertionError:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/unittest/mock.py", line 1179, in patched
return func(*args, **keywargs)
File "/app/tests/test_utils.py", line 15, in test_get_utc_timestamp
self.assertEqual(result, 1566895932.703618)
AssertionError: <MagicMock name='datetime().__sub__().total_seconds()' id='140475857850040'> != 1566895932.703618
我做错了什么?
任何帮助将不胜感激!
编辑:
感谢 ipaleka 对发生的事情的解释,因为我无法使用 mock 更改内置的 python 类,所以我需要创建一个 utcnow() 的自定义类来返回 test_utils.py 中的自定义时间:
class NewDate(datetime.datetime):
@classmethod
def utcnow(cls):
return cls(2019, 8, 27, 8, 52, 12, 703618)
datetime.datetime = NewDate
并将测试功能更改为:
def test_get_utc_timestamp(self):
result = get_utc_timestamp()
self.assertEqual(result, 1566895932.703618)
【问题讨论】:
-
您可以尝试将
@mock.patch('utils.datetime.datetime')替换为@mock.patch('datetime.datetime')吗?您可能正在“修补错误的名称”(请参阅docs.python.org/3/library/unittest.mock.html#where-to-patch) -
我替换了它,它仍然返回 AssertionError,我的包含 test_utils.py 的测试文件夹与 utils.py 处于同一顶层
标签: python datetime mocking python-unittest