python - python-3.3 的模拟工具

标签 python unit-testing python-3.x mocking python-3.3

我有一些类依赖于 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() 或模拟我的类,以及应该使用哪种工具来完成此类工作?

最佳答案

您可以使用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()

或者,您也可以使用 unittest.mock.Mock 来代替手动 MockPerfCounter :

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)

关于python - python-3.3 的模拟工具,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19338748/

相关文章:

python - 如何使用正则表达式或工具包将句子解析为标记

python - 将 pandas DataFrame 读取到 Stocker 时出现问题

python - 是否可以针对具有脚本文件路径参数名称的脚本文件调用 Python?

python - 如何将字典中的值放入变量

python - matplotlib geopandas 绘制 choropleth,并设置颜色方案的 bin

python - 使用 FileField wtforms 上传文件时将文件名存储在列中

python - 从 Swagger 编辑器生成 Swagger 服务器(Python Flask)时出错

unit-testing - 为什么 nUnit 测试经常在 Visual Studio 2015 中消失?

unit-testing - 创建测试请求时如何模拟简单的 POST 正文

python - 将 py.test 的输出作为对象读取