首页 > 解决方案 > 在 python unittest 中模拟睡眠功能

问题描述

我有一门课,我正在为之编写单元测试。

class MyClass(object):
  def __init__(max_time = DEFAULT.max):
    self.max_job_time = max_time
    self.start_time = time.time()

  def some_other_function():
    pass

  def run(sleep_time):
    exit_time = self.max_job_time + self.start_time

    while True:
      if time.time() > exit_time:
        break

      self.perform_some_other_function()
      
      if found_item:
        break
      else:
        time.sleep(sleep_time)
class MyManager(PY3TestCase, unittest.TestCase):
  @patch('time.sleep', return_value=None)
    def test_timeout(self, patched_time_sleep):
        my_custom_class = MyClass(max_time=3)

        time.sleep(60)
        with mock.patch.object(my_custom_class, 'some_other_function') as mock_poll:
            my_custom_class.run(1)
            my_custom_class.run(1)
            my_custom_class.run(1)

        # This should have been called exactly 0 times
        print(mock_poll.call_count, 1)
        self.assertEqual(mock_poll.call_count, 1)

我希望代码模拟等待 60 秒,尝试执行run然后立即退出,因为它应该模拟等待超过 max_time 的 60 秒。这会给我留下一个 mock_poll 被调用 0 次的结果,因为它永远不会到达some_other_function().

然而,结果some_other_function()被调用了约 34000 次。我相信这是因为它正确模拟了 time.sleep(60) 。但是这不符合退出时间的要求,当然,因为我们实际上并没有等待 60 秒。

我曾尝试在 StackOverflow 上寻找解决方案,这导致我找到了 patching 的初始解决方案time.sleep。我尝试过有人建议的另一个解决方案是将time.sleep补丁的返回值设置为大于max_time. 然而,这似乎没有做任何事情,它返回了大致相同的结果。

我的问题是,如何模拟time.sleep()以降低单元测试时间,同时还可以正确测试以正确检查MyClass超时并且不被调用?

标签: pythontimemockingpython-unittest

解决方案


推荐阅读