无法对列表理解中调用的方法进行mock.patch字典

时间:2019-03-11 20:49:48

标签: python unit-testing mocking

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

在理解Python中的模拟工作原理时,我是否缺少某些内容?我已经弄清楚了如果我模拟一个方法,是否传入一个空字典都没关系;它应该只返回True。

文件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

1 个答案:

答案 0 :(得分:1)

您的补丁应显示为class Rectangle: def __init__(self, height = 1, width = 1): self.height = height self.width = width

我将向您介绍原因:

@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来引用该函数,因此您仍然需要更深入一些。幸运的是,unittest.mock.patch拥有一个实用工具,可以模拟字典内容,如下所示:

method_dict

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

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

在这里,直到对f1.method1进行模拟之后才进行查找。在较早的情况下,您在读取file2时对函数进行了引用。在这里,直到实际调用该方法后,引用才会解析。