在python mock中作为副作用返回或中断?

时间:2015-02-19 23:07:56

标签: python mocking python-mock

我有一个多处理应用程序,工作程序在“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

所以我可以突破循环并完成测试。这些都不起作用,但有不同的方法来完成我想要完成的任务吗?

1 个答案:

答案 0 :(得分:2)

您可以使用Exception作为side_effect模拟sys.exit行为而不退出测试。

side_effect文档说:

  

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

所以你不能使用像breakreturn这样的语句,但你要做的是退出你的运行周期,这可以通过引发异常来获得...我希望你不要在线程的主要周期中使用狂野的try - except

我编写了一个简单示例来测试它,我使用了decorator 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())