我有一些类依赖于time.perf_counter()
来为事件添加时间戳,并在经过一段时间后执行操作,如下所示:
class Alarm:
def setAlarm(self):
self.alarmed = False
self._saved = time.perf_counter()
def runStep(self):
now = time.perf_counter()
if now - self._saved > 1000.0 and self._saved != -1:
self.alarmed = True
self._saved = -1
我想使用假时钟测试类Alarm
,它不一定是对time.perf_counter()
的调用(尽管它会更优雅,我猜)。我希望假时钟不会自行增加,而是根据我的命令,如下:
alarm = Alarm()
alarm.setAlarm()
clock.increment(999.0)
alarm.runStep()
self.assertFalse(alarm.alarmed)
clock.increment(1.1) # tick another second
alarm.runStep()
self.assertTrue(alarm.alarmed)
请问您如何模仿time.perf_counter()
或模拟我的课程,以及应该使用哪种工具进行此类工作?
答案 0 :(得分:2)
您可以使用unittest.mock
。
例如:
import time
import unittest
import unittest.mock
class Alarm:
def setAlarm(self):
self.alarmed = False
self._saved = time.perf_counter()
def runStep(self):
now = time.perf_counter()
if now - self._saved > 1000.0 and self._saved != -1:
self.alarmed = True
self._saved = -1
class MockPerfCounter:
def __init__(self):
self.t = 0
def increment(self, n):
self.t += n
def perf_counter(self):
return self.t
class TestAlarm(unittest.TestCase):
def test_foo(self):
clock = MockPerfCounter()
with unittest.mock.patch('time.perf_counter', clock.perf_counter):
alarm = Alarm()
alarm.setAlarm()
clock.increment(999.0)
alarm.runStep()
self.assertFalse(alarm.alarmed)
clock.increment(1.1) # tick another second
alarm.runStep()
self.assertTrue(alarm.alarmed)
if __name__ == '__main__':
unittest.main()
代替手动MockPerfCounter
,您也可以使用unittest.mock.Mock
:
class TestAlarm(unittest.TestCase):
def test_foo(self):
clock = unittest.mock.Mock()
clock.t = 0
with unittest.mock.patch('time.perf_counter', lambda: clock.t):
alarm = Alarm()
alarm.setAlarm()
clock.t += 999.0
alarm.runStep()
self.assertFalse(alarm.alarmed)
clock.t += 1.1
alarm.runStep()
self.assertTrue(alarm.alarmed)