I'm writing a unit test for a function that will confirm that a function called within it is called with the correct arguments. The problem is that one of the arguments is a generator.
Is there a way to compare the contents of the generator that fn
is called with using assert_has_calls
? An example of the behavior that I'm looking for is exhibited in 'AssertSequenceEqual.' As it is, test_use_fn
fails because the generator objects that it is comparing are different.
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])
You can use call_args_list
https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.call_args_list
I assume that you would check if every items of the generators are the same. I write a assertEqualGenerators()
method of the test case class that do the work (if the arguments are not generators use standard assertEqual()
). The module file name is mock_generators.py
and you must use mock_generators.fn
to patch fn
. The last trick is the call
object arguments: take a look to https://docs.python.org/3/library/unittest.mock.html#unittest.mock.call.call_list for the dettails of how fetch the data (in your case the first element is what you need).
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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.