Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python模拟中作为副作用返回还是中断?_Python_Mocking_Python Mock - Fatal编程技术网

在python模拟中作为副作用返回还是中断?

在python模拟中作为副作用返回还是中断?,python,mocking,python-mock,Python,Mocking,Python Mock,我有一个多处理应用程序,它让工人在“while True”循环中运行。对于测试,我希望能够以如下方式模拟sys.exit(): with mock.patch('sys.exit') as sys_mock: sys_mock.side_effect = break 或 这样我就可以打破这个循环,完成我的测试。这两种方法都不起作用,但有没有不同的方法来完成我试图完成的任务?您可以使用异常作为副作用来模拟sys.exit行为,而不必退出测试 文件说明: 这可以是调用mock时要调用的函数、i

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

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


这样我就可以打破这个循环,完成我的测试。这两种方法都不起作用,但有没有不同的方法来完成我试图完成的任务?

您可以使用
异常作为
副作用来模拟
sys.exit
行为,而不必退出测试

文件说明:

这可以是调用mock时要调用的函数、iterable或要引发的异常(类或实例)

因此,您不能使用像
break
return
这样的语句,但您要做的是退出运行周期,这可以通过引发异常来获得。。。我希望您不要在线程的主循环中使用wild
try
-
,除非使用

我编写了一个简单的示例来测试它,我使用decorator
patch
语法并将内联
side\u 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())

抱歉,我花了一点时间才回到这个话题。不过你的解决方案奏效了。抛出异常很好地打破了我的循环。谢谢
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())