如何在函数映射/字典中模拟函数?

时间:2017-11-05 14:22:39

标签: python python-3.x unit-testing mocking

我正在尝试修补fun_1字典中的worker_functions函数,我似乎在苦苦挣扎:

cli.py:
import sys

from worker_functions import (
    fun_1,
    fun_2,
    fun_3,
)

FUNCTION_MAP = {
    'run_1': fun_1,
    'run_2': fun_2,
    'run_3': fun_3,
}

def main():
    command = sys.argv[1]
    tag = sys.argv[2]
    action = FUNCTION_MAP[command]

    action(tag)

我尝试过模仿cli.fun_1cli.main.action以及cli.action,但这会导致失败。

test_cli.py:
from mock import patch

from cli import main


def make_test_args(tup):
    sample_args = ['cli.py']
    sample_args.extend(tup)
    return sample_args


def test_fun_1_command():
    test_args = make_test_args(['run_1', 'fake_tag'])
    with patch('sys.argv', test_args),\
         patch('cli.fun_1') as mock_action:
        main()

        mock_action.assert_called_once()

我似乎错过了什么吗?

1 个答案:

答案 0 :(得分:1)

您需要修补FUNCTION_MAP字典本身的引用。使用patch.dict() callable执行此操作:

from unittest.mock import patch, MagicMock

mock_action = MagicMock()
with patch('sys.argv', test_args),\
     patch.dict('cli.FUNCTION_MAP', {'run_1': mock_action}):
    # ...

那是因为FUNCTION_MAP字典是查找函数引用的位置。