Skip to content

Commit 1600d78

Browse files
authored
gh-113569: Display calls in Mock.assert_has_calls failure when empty (GH-113573)
1 parent 1ae7ceb commit 1600d78

File tree

3 files changed

+28
-18
lines changed

3 files changed

+28
-18
lines changed

Lib/test/test_unittest/testmock/testmock.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,25 +1547,33 @@ def f(x=None): pass
15471547
mock = Mock(spec=f)
15481548
mock(1)
15491549

1550-
with self.assertRaisesRegex(
1551-
AssertionError,
1552-
'^{}$'.format(
1553-
re.escape('Calls not found.\n'
1554-
'Expected: [call()]\n'
1555-
' Actual: [call(1)]'))) as cm:
1550+
with self.assertRaises(AssertionError) as cm:
15561551
mock.assert_has_calls([call()])
1552+
self.assertEqual(str(cm.exception),
1553+
'Calls not found.\n'
1554+
'Expected: [call()]\n'
1555+
' Actual: [call(1)]'
1556+
)
15571557
self.assertIsNone(cm.exception.__cause__)
15581558

1559+
uncalled_mock = Mock()
1560+
with self.assertRaises(AssertionError) as cm:
1561+
uncalled_mock.assert_has_calls([call()])
1562+
self.assertEqual(str(cm.exception),
1563+
'Calls not found.\n'
1564+
'Expected: [call()]\n'
1565+
' Actual: []'
1566+
)
1567+
self.assertIsNone(cm.exception.__cause__)
15591568

1560-
with self.assertRaisesRegex(
1561-
AssertionError,
1562-
'^{}$'.format(
1563-
re.escape(
1564-
'Error processing expected calls.\n'
1565-
"Errors: [None, TypeError('too many positional arguments')]\n"
1566-
"Expected: [call(), call(1, 2)]\n"
1567-
' Actual: [call(1)]'))) as cm:
1569+
with self.assertRaises(AssertionError) as cm:
15681570
mock.assert_has_calls([call(), call(1, 2)])
1571+
self.assertEqual(str(cm.exception),
1572+
'Error processing expected calls.\n'
1573+
"Errors: [None, TypeError('too many positional arguments')]\n"
1574+
'Expected: [call(), call(1, 2)]\n'
1575+
' Actual: [call(1)]'
1576+
)
15691577
self.assertIsInstance(cm.exception.__cause__, TypeError)
15701578

15711579
def test_assert_any_call(self):

Lib/unittest/mock.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,8 +1010,8 @@ def assert_has_calls(self, calls, any_order=False):
10101010
for e in expected])
10111011
raise AssertionError(
10121012
f'{problem}\n'
1013-
f'Expected: {_CallList(calls)}'
1014-
f'{self._calls_repr(prefix=" Actual").rstrip(".")}'
1013+
f'Expected: {_CallList(calls)}\n'
1014+
f' Actual: {safe_repr(self.mock_calls)}'
10151015
) from cause
10161016
return
10171017

@@ -1085,7 +1085,7 @@ def _get_child_mock(self, /, **kw):
10851085
return klass(**kw)
10861086

10871087

1088-
def _calls_repr(self, prefix="Calls"):
1088+
def _calls_repr(self):
10891089
"""Renders self.mock_calls as a string.
10901090
10911091
Example: "\nCalls: [call(1), call(2)]."
@@ -1095,7 +1095,7 @@ def _calls_repr(self, prefix="Calls"):
10951095
"""
10961096
if not self.mock_calls:
10971097
return ""
1098-
return f"\n{prefix}: {safe_repr(self.mock_calls)}."
1098+
return f"\nCalls: {safe_repr(self.mock_calls)}."
10991099

11001100

11011101
# Denylist for forbidden attribute names in safe mode
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Indicate if there were no actual calls in unittest
2+
:meth:`~unittest.mock.Mock.assert_has_calls` failure.

0 commit comments

Comments
 (0)