我有一个包含时间戳的类。在init函数中,初始时间戳设置为提供的参数,默认值为' time.monotonic()'。我也有更新功能来设置时间戳,也使用time.monotonic()
在对这个类进行单元测试时,我想模拟出time.monotonic,以获得可预测的结果。
但是,默认参数中的调用始终是实时的。单调
ClassWithTimestamp.py:
import time
class ClassWithTimestamp:
def __init__(self, value={}, timestamp=time.monotonic()):
self.timestamp = timestamp
def update(self):
self.timestamp = time.monotonic()
ClassWithTimestampTest.py:
import unittest
from unittest import mock
import ClassWithTimestamp
class ClassWithTimestampTest(unittest.TestCase):
def setUp(self):
ClassWithTimestamp.time.monotonic = mock.Mock(name='now')
ClassWithTimestamp.time.monotonic.return_value = 1000
def tearDown(self):
pass
def test_init(self):
sut = ClassWithTimestamp.ClassWithTimestamp()
self.assertEqual(sut.timestamp, 1000)
def test_update(self):
sut = ClassWithTimestamp.ClassWithTimestamp()
sut.update()
self.assertEqual(sut.timestamp, 1000)
if __name__ == '__main__':
unittest.main()
运行时:
python3 ClassWithTimestampTest.py -v
test_init (__main__.ClassWithTimestampTest) ... FAIL
test_update (__main__.ClassWithTimestampTest) ... ok
======================================================================
FAIL: test_init (__main__.ClassWithTimestampTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "ClassWithTimestampTest.py", line 16, in test_init
self.assertEqual(sut.timestamp, 1000)
AssertionError: 762811.874163785 != 1000
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
答案 0 :(得分:0)
我发现了这个:
"Least Astonishment" and the Mutable Default Argument
它解释了我的问题,默认参数在定义init函数时调用,而不是执行它。
因为我打算将时间戳设置为构建时间,所以我的代码开始有问题。
我的修改后的代码是
def __init__(self, value={}, timestamp=None):
if timestamp:
self.timestamp = timestamp
else:
self.timestamp = time.monotonic()
问题本身仍然存在,我看到的唯一方法是在构造后用模拟函数的输出覆盖类的成员。