未能模拟.列表理解中调用的方法词典



我当前正在使用以下设置来管理可以应用于数据的可变方法集,但是当我尝试模拟该方法以确保其返回任何列表时(我已经对方法本身设置了测试),我最终得到了KeyErrors。

我在理解Python的嘲笑工作时是否缺少一些东西?我弄清楚了是否嘲笑一种方法,如果我传递了一个空词典都不重要。那时候应该返回真实。

文件1

def method_1(data):
    return data['header_1'] > 1
def method_2(data):
    return data['header_2'] > 1
def method_3(data):
    return data['header_3'] > 1

文件2

from module import file1 as f1
method_dict = {
    'method_1' : f1.method1,
    'method_2' : f1.method2,
    'method_3' : f1.method3
}
tasks_1 = ['method_1']
tasks_2 = ['method_2', 'method_3']
def function_A(data, tasks):
    results = [method_dict[task](data) for task in tasks]
    index = [i for i, result in enumerate(results) if result is True]
    return [tasks[i] for i in index] 

测试文件

from module import file2 as f2
from unittest import TestCase
from unittest.mock import patch
class TestFile2(TestCase):
    @patch('module.file1.method_1')
    def test_file_2(self, mock_method_1):
        mock_method_1.return_value = True
        results = f2.function_A({}, 'tasks_1')
        expected = ['method_1']
        self.assertEqual(results, expected)
. . .

错误

test/test_determine_failure_modes.py:100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
module/file2.py:82: in function_A
    results = [task[task](data) for task in tasks]
module/file2.py:82: in <listcomp>
    results = [tasks[task](data) for task in tasks]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
data = {}
    def method_1(data):
>       return data['header_1'] > 1
E       KeyError: 'header_1'
module/file1.py:2: KeyError

您的补丁应该读取@patch('module.file2.f1.method_1')

我会引导你了解为什么:

test_determine_failure_modes.py导入file1 as f1。然后读取file1,并在当地人中定义method1。在符号f1

上可用

所以符号表看起来像:

file1: {'method1': <function>, <METHOD_1>, ...}
f1: {'method1': <function>, <METHOD_1>, ...}

然后您修补file1.method1,然后获得此符号表

file1: {'method1': <function>, MOCK, ...}
f1: {'method1': <function>, <METHOD_1>, ...}

然后您致电f1.method1并获取实际功能。

看起来您使用method_dict来引用该功能,因此您仍然需要更深入一些。幸运的是,unittest.mock.patch具有嘲笑类似dict内容的实用程序:

with patch.dict(f2.method_dict, {'method1': your_mock_here}):
    your_test_here()

另一种方法是推迟解决方法名称,直到被嘲笑。

method_dict = {
    'method_1' : lambda data: f1.method1(data),
    'method_2' : lambda data: f1.method2(data),
    'method_3' : lambda data: f1.method3(data)
}

在这里,直到被嘲笑之后才能进行F1.Method1的查找。在较早的情况下,您在读取File2时对函数进行了引用。在这里,直到实际调用该方法之前,该参考才能解决。

最新更新