Python 比较mock.assert\u中的生成器对象是否有\u调用

Python 比较mock.assert\u中的生成器对象是否有\u调用,python,mocking,Python,Mocking,我正在为一个函数编写一个单元测试,该测试将确认在其中调用的函数是使用正确的参数调用的。问题是其中一个参数是生成器 是否有一种方法可以比较使用调用fn的生成器的内容?我正在寻找的行为示例显示在“AssertSequenceEqual”中。实际上,test\u use\u fn失败,因为它所比较的生成器对象不同 import mock def fn(entries): pass def use_fn(entries, convert=lambda x: x): entries =

我正在为一个函数编写一个单元测试,该测试将确认在其中调用的函数是使用正确的参数调用的。问题是其中一个参数是生成器

是否有一种方法可以比较使用调用
fn
的生成器的内容?我正在寻找的行为示例显示在“AssertSequenceEqual”中。实际上,
test\u use\u fn
失败,因为它所比较的生成器对象不同

import mock

def fn(entries):
    pass

def use_fn(entries, convert=lambda x: x):
    entries = (convert(entry) for entry in entries)
    entries = fn(entries)
    entries = fn(entries)

@mock.patch('fn')
def test_use_fn(self, mock_fn):
    mock_fn.return_value = 'baz'
    entries = ['foo', 'bar']
    use_fn(entries)
    call_1 = mock.call((entry for entry in entries))
    call_2 = mock.call('baz')
    mock_fn.assert_has_calls([call_1, call_2])

您可以使用
call\u args\u list

我假设您会检查发电机的每个项目是否相同。我编写了测试用例类的
assertEqualGenerators()
方法来完成这项工作(如果参数不是生成器,则使用标准的
assertEqual()
)。模块文件名为
mock\u generators.py
,您必须使用
mock\u generators.fn
来修补
fn
。最后一个技巧是
调用
对象参数:查看如何获取数据的详细信息(在您的示例中,第一个元素就是您所需要的)


没有两个生成器对象是相同的,因此它们总是会在相等或
is
测试中失败。嵌套的内部函数也是如此。你能进一步解释一下你为什么要核实这样的电话吗?@Aruistante,我知道;这是问题的核心。我正在寻找的一个行为示例显示在“assertSequenceEqual”中。
assertEqualGenerators()
中使用
itertools.zip\u longest()
<如果一个生成器比另一个生成器长,则code>zip()将无法报告差异。您应该使用一个“不可能”的fillvalue,例如
object()
,这样它就不会意外地比较equal。
import unittest
from unittest import mock

def fn(entries):
    pass

def use_fn(entries, convert=lambda x: x):
    entries = (convert(entry) for entry in entries)
    entries = fn(entries)
    entries = fn(entries)

class MyTestCase(unittest.TestCase):

    def assertEqualGenerators(self,a,b):
        try:
            for x,y in zip(a,b):
                self.assertEqual(x, y)
        except TypeError:
            self.assertEqual(a, b)

    @mock.patch("mock_generators.fn")
    def test_use_fn(self, mock_fn):
        mock_fn.return_value = 'baz'
        entries = ['foo', 'bar']
        use_fn(entries)
        calls = [mock.call((entry for entry in entries)),
                    mock.call('baz')]
        self.assertEqual(len(calls), mock_fn.call_count)
        for a,b in zip(mock_fn.call_args_list,calls):
            self.assertEqualGenerators(a[0],b[0])


if __name__ == '__main__':
    unittest.main()