我目前正在使用以下设置来管理可以应用于数据的可变方法集,但是当我尝试模拟该方法以确保它返回任何列表时(我已经设置了测试方法本身),最后出现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
答案 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时对函数进行了引用。在这里,直到实际调用该方法后,引用才会解析。