2

我有一个多处理应用程序,它的工作人员在“while True”循环中运行。对于测试,我希望能够以这样的方式模拟 sys.exit() :

with mock.patch('sys.exit') as sys_mock:
  sys_mock.side_effect = break

或者

with mock.patch('sys.exit') as sys_mock:
  sys_mock.side_effect = return

所以我可以跳出循环并完成我的测试。这些都不起作用,但是有没有不同的方法来做我想要完成的事情?

4

1 回答 1

3

您可以使用Exceptionasside_effect来模拟sys.exit行为而无需退出测试。

side_effect文件说:

这可以是调用模拟时要调用的函数、可迭代的或要引发的异常(类或实例)。

因此,您不能使用or之类的语句,但您想做的是退出运行周期,这可以通过引发异常来获得……我希望您不要在线程的主周期中使用 wild - 。breakreturntryexcept

我写了一个简单的例子来测试它,我使用了装饰器patch语法并内联side_effect=Exception,使测试更具可读性:

import sys
import threading
import unittest
from unittest.mock import patch

class T(threading.Thread):
    def __init__(self,  *args, **kwargs):
        super(T, self).__init__(*args, **kwargs)
        self._interrupt = threading.Event()
        self.started = threading.Event() #Used to be sure that we test run() behavior 
        self.started.clear()
        self.terminated = False

    def interrupt(self):
        self._interrupt.set()

    def run(self, *args, **kwargs):
        self._interrupt.clear()
        self.started.set()
        while not self._interrupt.is_set():
            self._interrupt.wait(timeout=1)
        self.terminated = True
        sys.exit()


class TestInterrupt(unittest.TestCase):

    @patch("sys.exit", side_effect=Exception("Ignore it... just close thread"))
    def test_interrupt(self, mock_sys_exit):
        t = T()
        t.start()
        if not t.started.is_set():
            t.started.wait(timeout=0.2)
        self.assertTrue(t.started.is_set(), "t not started!")
        #Ok t is in run() main cycle: we can test interrupt
        t.interrupt()
        t.join(0.1)
        self.assertTrue(t.terminated)
        self.assertFalse(t.isAlive())
于 2015-02-20T08:32:44.513 回答