我正在为一个函数编写单元测试,该函数将确认使用正确的参数调用其中调用的函数。问题是其中一个参数是生成器。
有没有办法比较使用assert_has_calls
调用fn
的生成器的内容?我正在寻找的行为的一个例子展示在'AssertSequenceEqual'中。实际上,test_use_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])
答案 0 :(得分:2)
您可以使用call_args_list
https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.call_args_list
我假设您要检查发电机的每个项目是否相同。我编写了一个测试用例类的assertEqualGenerators()
方法来完成工作(如果参数不是生成器,则使用标准assertEqual()
)。模块文件名为mock_generators.py
,您必须使用mock_generators.fn
修补fn
。最后一个技巧是call
对象参数:看看https://docs.python.org/3/library/unittest.mock.html#unittest.mock.call.call_list是否有关于获取数据的详细信息(在您的情况下,第一个元素是您需要的)。
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()