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

fox*_*lue 1 python unit-testing mocking python-3.x

我正在尝试修补字典fun_1中的功能worker_functions,但我似乎很挣扎:

剪辑.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)
Run Code Online (Sandbox Code Playgroud)

我尝试过嘲笑cli.fun_1and cli.main.action,cli.action但这会导致失败。

测试_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()
Run Code Online (Sandbox Code Playgroud)

我似乎错过了什么吗?

Mar*_*ers 5

您需要修补FUNCTION_MAP字典本身中的引用。使用patch.dict()可调用函数来执行此操作:

from unittest.mock import patch, MagicMock

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

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