Python:如何在列表理解中模拟高阶函数

时间:2019-05-08 14:08:53

标签: python mocking python-unittest map-function functools

为了学习模拟,我试图为我拥有的脚本设置单元测试。我被困在一个包含map()partial()的函数上,我不知道如何模拟它们的输出。

我已经在其他一些函数中为可迭代对象设置了模拟,并且已经按照How to let MagicMock behave like a dict?进行了__iter__方法的尝试,并阅读了关于模拟的文档,但是我不能使它可以使用此功能。使用真实数据进行测试时,该功能可以正常工作。

该函数本身应该通过搜索attr_list返回的元素来获取find_elements()中指定的属性,并将其作为数据帧返回。我使用map()将属性列表应用于ElementTree get()函数,并使用partial()始终使用default=0https://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.get)。

我只想测试这部分,所以我同时修补了find_elementscreate_dataframe

功能:

def get_attributes(xml, tag, attr_list):
    attr_list.insert(0, 't') # time (always wanted and hence not specified in attr_list)
    elements = find_elements(xml, tag)
    values = [map(partial(element.get, default=0), attr_list) for element in elements]
    return create_dataframe(values, attr_list)

测试:

@patch('reports.create_dataframe')
@patch('reports.find_elements')
def test_attribute_values_are_added_to_df(self, mocked_find, mocked_create):
    data = [10, 1, 2]
    attr_list = ['t', 'attr1', 'attr2']
    element = MagicMock()
    mocked_find.return_value = [element]
    element.get.return_value = data
    reports.get_attributes('xmlfile', 'tag', ['attr1', 'attr2'])
    mocked_create.assert_called_once_with([10, 1, 2], columns=attr_list)

运行此测试时,我得到:

AssertionError: Expected call: create_dataframe([10, 1, 2], ['t', 'attr1', 'attr2'])
Actual call: create_dataframe([<map object at 0x7f5417c07048>], ['t', 'attr1', 'attr2'])

我想做的是使对象mocked_find返回一个MagicMock对象的列表,该对象在迭代时将返回指定的data列表,然后可以将该列表传递给create_dataframe,但显然并非如此。我可能会误解了您应该如何为这种功能编写单元测试。任何帮助将不胜感激。

0 个答案:

没有答案