如何在python中模拟/修补关联数组

如何在python中模拟/修补关联数组,python,unit-testing,python-mock,Python,Unit Testing,Python Mock,我有一个模块,其中一个字典作为关联数组来实现一种switch语句 def my_method1(): return "method 1" def my_method2(): return "method 2" map_func = { '0': my_method1, '1': my_method2 } def disptach(arg): return map_func[arg]() 如何在测试中模拟我的_方法1?我尝试了以下方法但没有成功: i

我有一个模块,其中一个字典作为关联数组来实现一种switch语句

def my_method1():
    return "method 1"


def my_method2():
    return "method 2"


map_func = {
    '0': my_method1,
    '1': my_method2
}

def disptach(arg):
  return map_func[arg]()
如何在测试中模拟我的_方法1?我尝试了以下方法但没有成功:

import my_module as app

@patch('my_module.my_method1')
def test_mocking_sample(self, my_mock):
    my_mock.return_value = 'mocked'
    assert_equal('mocked',app.dispatch('0'))
有什么想法吗?

这篇文档说明了以下内容:

修补程序通过(临时)更改名称指向的对象来工作 还有一个。可以有许多名字指向任何个人 对象,因此要进行修补,必须确保修补 被测系统使用的名称

基本上,您的调度器不会看到它,因为在应用补丁之前,映射是为了引用原始方法而构建的

要使其可模拟,最简单的方法是将映射折叠到
dispatch
函数中:

def dispatch(arg):
  return {
    '0': my_method1,
    '1': my_method2
  }[arg]()
这样做的缺点是每次调用时都会重建映射,因此速度会较慢

为了稍微聪明一点,Python似乎允许您交换函数的实际代码,如下所示:

>>> f = lambda: "foo"
>>> a = f
>>> g = lambda: "bar"
>>> f.func_code = g.func_code
>>> a()
'bar'

我不建议您这样做,但也许您可以找到一个支持类似内容的模拟框架。

正如您所发现的,修补
my_Method1()
不起作用。这是因为导入my_模块时定义了
map_func['0']
,对
my_Method1()
的后续更改不会为您的测试更新
map_func
。相反,我们需要在dictionary
map\u func
中直接为键
'0'
修补值。unittest.mock解释了如何修补字典条目。以下是您的测试的工作实现:

""" test_my_module.py
"""
import unittest
import unittest.mock as mock
import my_module as app


my_mock = mock.MagicMock()


class Test_mock_sample(unittest.TestCase):

    @mock.patch.dict('my_module.map_func', {'0': my_mock})
    def test_mocking_sample(self):
        my_mock.return_value = 'mocked'
        self.assertEqual('mocked', app.dispatch('0'))

if __name__ == '__main__':
    unittest.main()
将原始my_模块中的
dispatch
更改为
dispatch

""" my_module.py
"""
def my_method1():
    return "method 1"


def my_method2():
    return "method 2"


map_func = {
    '0': my_method1,
    '1': my_method2
}

def dispatch(arg):
  return map_func[arg]()
然后,命令python-m unittest test_my_module给出以下输出:

.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

成功了

我想您必须模拟分派('0')而不是我的方法1。当使用参数“0”调用时,这是模拟分派。